Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用define_方法和eval的动态方法_Ruby_Metaprogramming_Eval_Dynamic Method_Class Eval - Fatal编程技术网

Ruby 使用define_方法和eval的动态方法

Ruby 使用define_方法和eval的动态方法,ruby,metaprogramming,eval,dynamic-method,class-eval,Ruby,Metaprogramming,Eval,Dynamic Method,Class Eval,我将两个示例类放在一起,它们以几种不同的方式实现,很好地反映了我希望在Rails模型中执行的操作。我担心的是,我不知道使用这两种方法会有什么问题。我只找到了解释如何实现它们的帖子,或者在使用它们时要避免/小心的一般警告。我没有找到一个明确的解释,说明如何安全地实现这一点,以及我正在注意什么,或者为什么我应该避免这种模式 class X attr_accessor :yn_sc, :um_sc def initialize @yn_sc = 0 @um_sc = 0 e

我将两个示例类放在一起,它们以几种不同的方式实现,很好地反映了我希望在Rails模型中执行的操作。我担心的是,我不知道使用这两种方法会有什么问题。我只找到了解释如何实现它们的帖子,或者在使用它们时要避免/小心的一般警告。我没有找到一个明确的解释,说明如何安全地实现这一点,以及我正在注意什么,或者为什么我应该避免这种模式

class X
  attr_accessor :yn_sc, :um_sc
  def initialize
    @yn_sc = 0
    @um_sc = 0
  end
  types = %w(yn um)
  types.each do |t|
    define_method("#{t}_add") do |val|
      val = ActiveRecord::Base.send(:sanitize_sql_array, ["%s", val])
      eval("@#{t}_sc += #{val}")
    end
  end
end

class X
  attr_accessor :yn_sc, :um_sc
  def initialize
    @yn_sc = 0
    @um_sc = 0
  end
  types = %w(yn um)
  types.each do |t|
    # eval <<-EVAL also works
    self.class_eval <<-EVAL 
      def #{t}_add(val)
        @#{t}_sc += val
      end
    EVAL
  end
end


x = X.new
x.yn_add(1) #=> x.yn_sc == 1 for both
X类
属性存取器:yn\u sc,:um\u sc
def初始化
@yn_sc=0
@um_sc=0
结束
类型=%w(yn-um)
类型。每个类型都有|
定义方法(“#{t}_add”)do|val|
val=ActiveRecord::Base.send(:清理sql数组,[%s],val])
eval(“@{t}u sc+={val}”)
结束
结束
结束
X类
属性存取器:yn\u sc,:um\u sc
def初始化
@yn_sc=0
@um_sc=0
结束
类型=%w(yn-um)
类型。每个类型都有|

#eval嗯,你的代码看起来真的很安全。但是想象一下一个基于用户输入的代码。可能看起来像

puts 'Give me an order, sir!'
order = gets.chomp
eval(order)
如果我们的船长放肆地命令我们
'rm-rf~/'
,会发生什么?可悲的事情是肯定的

因此,请接受一点教训
eval
不安全,因为它会计算它接收到的每个字符串。
但是还有另一个原因不使用
eval
。有时,它的评估速度比备选方案慢。如果感兴趣,请查看。

好吧,
val
将是用户从表单中输入的内容,尽管我知道恶意用户可以通过各种方式欺骗它,因此,
清理