Ruby:erb 抛出错误“结果”:无法将字符串转换为整数(类型错误)”

发布于 2024-09-28 12:32:24 字数 2857 浏览 7 评论 0原文

快速背景:我正在设置一个快速但肮脏的模板方案,其中所有模板文件都命名为“*.erb”。填充数据驻留在 yaml 文件中。输出为模板名称减去“.erb”的文件。

我没有对 erb 做太多工作,并且收到错误“`result':无法将 String 转换为 Integer (TypeError)”...这对我来说没有多大意义。

这是完成这项工作的类 (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}" )
    @[email protected] 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

yaml 文件 (test.yaml):

--- 
test_id: XXX123

模板文件 (test.txt.erb):

Line 1
Line 2 test_id: <%= i['test_id'] %>
Line 3

驱动整个混乱的代码 (test.rb):

#! /usr/bin/ruby

require "generate_interface"

test_interface = GenerateInterface.new( "test.yaml" )
test_interface.gobutton

最后,输出和错误消息:

$ 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

我认为 _erbout.concat(( i['test_id'] ).to_s) 有问题,但是当我显式打印 ( i['test_id'] ).to_s 时,我得到 'XXX123'这是我所期望的。

Quick background: I'm setting up a quick and dirty templating scheme where all of my template files are named '*.erb'. the fill in data resides in a yaml file. Output is to files with the name of the template, minus '.erb'.

I haven't done much work with erb, and I'm getting the error "`result': can't convert String into Integer (TypeError)" ... which doesn't make much sense to me.

Here's the class that does the work (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}" )
    @[email protected] 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

The yaml file (test.yaml):

--- 
test_id: XXX123

The template file (test.txt.erb):

Line 1
Line 2 test_id: <%= i['test_id'] %>
Line 3

The code that drives the whole mess (test.rb):

#! /usr/bin/ruby

require "generate_interface"

test_interface = GenerateInterface.new( "test.yaml" )
test_interface.gobutton

And finally, the output and error messages:

$ 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

I figured that there was something wrong with _erbout.concat(( i['test_id'] ).to_s), but when I explicitly print ( i['test_id'] ).to_s I get 'XXX123' which is what I expect.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我入戏太深 2024-10-05 12:32:24

(您粘贴的generate_interface.rb错过了最后的end

直接的问题是Erb.initialize的第二个参数是安全级别;第三个是装饰选项。您的装饰选项被解释为安全水平。

要解决此问题,请更改

  message = ERB.new(template, "%<>" )

  message = ERB.new(template, nil, "%<>" )

第二个问题是变量 i 不会自动用于您的模板代码。要解决此问题,您需要传入一个绑定,更改

  result = message.result

  result = message.result(binding)

在下面的行中,将 message.result 更改为 result

(Your paste of generate_interface.rb missed the final end)

The immediate problem is that the second argument to Erb.initialize is the safe level; the third being the trim options. Your trim options are being interpreted as a safe level.

To fix that, change

  message = ERB.new(template, "%<>" )

to

  message = ERB.new(template, nil, "%<>" )

The second problem is that variable i is not automatically available to your template code. To fix that, you need to pass in a binding, changing

  result = message.result

to

  result = message.result(binding)

In the line following, change message.result to result

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文