在Ruby中,class_eval << – “end_eval”,__FILE__,__LINE__是什么意思?

我正在学习如何在模块中使用class_eval(我对class_eval有点熟悉),并在resource_controller中遇到了这个有用的类 。 在那里他们有这样的事情:

class_eval <<-"end_eval", __FILE__, __LINE__ def #{block_accessor}(*args, &block) unless args.empty? && block.nil? args.push block if block_given? @#{block_accessor} = [args].flatten end @#{block_accessor} end end_eval 

__FILE____LINE__在这方面做了什么? 我知道__FILE__引用当前文件,但整个事情到底做了什么? 真的不知道如何search:)。

3 Solutions collect form web for “在Ruby中,class_eval << – “end_eval”,__FILE__,__LINE__是什么意思?”

__FILE____LINE__是一些dynamic常量,用于保存当前正在执行的文件和行。 在这里传递他们允许错误正确报告他们的位置。

 instance_eval <<-end_eval, __FILE__, __LINE__ def foo a = 123 b = :abc a.send b end end_eval foo 

当你运行这个

 $ ruby foo.rb foo.rb:5:in `send': undefined method `abc' for 123:Fixnum (NoMethodError) from foo.rb:5:in `foo' from foo.rb:11 

注意它说的是文件和第5行,即使这只是eval中的文本。 如果没有这些文件/行的技巧,输出将如下所示:

 $ ruby foo.rb (eval):5:in `send': undefined method `abc' for 123:Fixnum (NoMethodError) from (eval):5:in `foo' from foo.rb:11 

堆栈跟踪只显示(eval) ,这不是很有帮助。

<<是一个heredoc的开始。 该行是多行string的开始。 该string被删除以创build该函数。 class_eval函数使用__FILE__和__LINE__来添加debugging信息。

我们还要注意,应尽可能避免evalstring。 在你的情况下,用#class_evalreplace#class_eval是可能的,应该是首选的:

 class_exec do define_method block_accessor do |*args, &block| unless args.empty? && block.nil? args.push block if block_given? instance_variable_set "@#{block_accessor}", [args].flatten end instance_variable_get "@#{block_accessor}" end end 
  • Ruby模块中的常量范围
  • 添加自定义字段/列来deviseRails 4
  • Ruby数组find_first对象?
  • Rspec 3如何testingFlash消息
  • Rails 3.1和图像资产
  • 如何禁用控制台中的MongoDB日志消息?
  • 如何检查文件的存在
  • 使用--no-rdoc和--no-ri与bundler
  • 使用Ruby将大写string转换为标题大小写
  • Array#each与Array#map
  • 在Rails 4中如何使用attr_accessible?