我不懂class_eval

class Module
  def attr_ (*syms)
    syms.each do |sym|
      class_eval %{def #{sym}= (val)
        @#{sym} = val
      end}
    end
  end
end
%是什么意思?
class_eval是做什么的?
(val)来自哪里?

最佳答案

简短的答案是:您可能想要避免使用class_eval这样的代码。

这是您的代码的说明:
%{hello}只是在Ruby中编写字符串文字的另一种方式,而不必担心在字符串中转义双引号或单引号:

%{hello "world"} == "hello \"world\""  # => true

您代码中的val是所定义方法的参数。
class_eval用于定义一些方法,方法是计算要编写的文本以进行定义,然后对其求值。顺便说一句,这里没有必要。等效代码为:
class Module
  def attr_ (*syms)
    syms.each do |sym|
      define_method "#{sym}=" do |val|
        instance_variable_set "@#{sym}", val
      end
    end
  end
end

这仅等效于内置的attr_writer

更新:两者之间实际上可能存在显着差异。

如果您不信任class_eval参数,则syms版本容易受到攻击。例如:
class Foo
  attr_ "x; end; puts 'I can execute anything here!'; val=42; begin; val"
end
class_eval版本将打印两次“我可以在这里执行任何操作”,证明它可以执行任何操作。 define_method版本不会打印任何内容。

type of code对于为所有已安装的Rails应用程序创建major vulnerability至关重要。

09-13 11:21