Ruby: erreur de lancer erb « ` résultat ": ne peut pas convertir chaîne en entier (TypeError) »
Question
Arrière-plan rapide: Je suis mise en place d'un système de templating rapide et sale où tous mes fichiers de modèle sont nommés « * .erb ». le remplissage de données réside dans un fichier yaml. La sortie est de fichiers avec le nom du modèle, moins « .erb ».
Je ne l'ai pas fait beaucoup de travail avec erb, et je reçois l'erreur « ` résultat ": ne peut pas convertir chaîne en entier (TypeError) ». ... qui ne fait pas de sens pour moi
Voici la classe qui fait le travail (generate_interface.rb):
#! /usr/bin/ruby
require 'yaml'
require 'erb'
class GenerateInterface
def initialize(yamlfile)
@yamlfile = yamlfile
@erbfiles = Dir.glob("*.erb")
end
def gobutton
# i -- interface. kept short because it's used all over the place in the erb files.
i = YAML.load_file( @yamlfile )
puts( "i: #{i.inspect}" )
puts( "i['test_id']: #{i['test_id'].inspect}" )
puts( "( i['test_id'] ).to_s: #{( i['test_id'] ).to_s}" )
@outfile=@erbfiles.map do
|erbfile|
puts( "erbfile: #{erbfile.inspect}" )
outfile = erbfile.gsub(/\.erb$/,"")
puts( "outfile: #{outfile.inspect}" )
template = File.open( erbfile, 'r' ) { |f| f.read }
puts( "template: #{template.inspect}" )
message = ERB.new(template, "%<>" )
puts( "message: #{message.inspect}" )
result=message.result
puts( "result: #{result.inspect}" )
File.open(outfile, 'w' ) { |f| f.write( message.result) }
end
end
end
Le fichier YAML (de test.yaml):
---
test_id: XXX123
Le fichier modèle (test.txt.erb):
Line 1
Line 2 test_id: <%= i['test_id'] %>
Line 3
Le code qui anime tout ce gâchis (test.rb):
#! /usr/bin/ruby
require "generate_interface"
test_interface = GenerateInterface.new( "test.yaml" )
test_interface.gobutton
Et enfin, les messages de sortie et d'erreur:
$ ruby -d test.rb
Exception `NoMethodError' at /usr/lib/ruby/1.8/rational.rb:78 - undefined method `gcd' for Rational(1, 2):Rational
i: {"test_id"=>XXX123}
i['test_id']: XXX123
( i['test_id'] ).to_s: XXX123
erbfile: "test.txt.erb"
outfile: "test.txt"
template: "Line 1\nLine 2 test_id: <%= i['test_id'] %>\nLine 3\n"
message: #<ERB:0xb74ac150 @src="_erbout = ''; _erbout.concat \"Line 1\\nLine 2 test_id: \"\n; _erbout.concat(( i['test_id'] ).to_s); _erbout.concat \"\\nLine 3\\n\"\n\n; _erbout", @safe_level="%<>", @filename=nil>
Exception `TypeError' at /usr/lib/ruby/1.8/erb.rb:715 - can't convert String into Integer
/usr/lib/ruby/1.8/erb.rb:715:in `result': can't convert String into Integer (TypeError)
from /usr/lib/ruby/1.8/erb.rb:714:in `call'
from /usr/lib/ruby/1.8/erb.rb:714:in `result'
from ./generate_interface.rb:26:in `gobutton'
from ./generate_interface.rb:17:in `map'
from ./generate_interface.rb:17:in `gobutton'
from test.rb:6
Je me suis dit qu'il y avait quelque chose de mal avec _erbout.concat ((i [ 'test_id']) .to_s), mais quand j'imprime explicitement (i [ 'test_id']) .to_s je reçois 'XXX123' qui est ce que Je me attends.
La solution
(Votre pâte de generate_interface.rb manqué le end
final)
Le problème immédiat est que le second argument de Erb.initialize
est le niveau de sécurité; le troisième étant les options de finition. Vos options de finition sont interprétées comme un niveau de sécurité.
Pour résoudre ce problème, le changement
message = ERB.new(template, "%<>" )
à
message = ERB.new(template, nil, "%<>" )
Le deuxième problème est que i
variable n'est pas automatiquement disponible à votre code de modèle. Pour résoudre ce problème, vous devez passer dans une liaison, en changeant
result = message.result
à
result = message.result(binding)
Dans la ligne suivante, changement message.result
à result