简体   繁体   English

我如何使用class_eval?

[英]How do I use class_eval?

I don't understand class_eval . 我不懂class_eval

class Module
  def attr_ (*syms)
    syms.each do |sym|
      class_eval %{def #{sym}= (val)
        @#{sym} = val
      end}
    end
  end
end

What does the % mean? %是什么意思?

What does class_eval do? class_eval做什么?

And where is (val) coming from? (val)来自哪里?

The short answer is: you probably want to avoid using class_eval like this. 简短的回答是:您可能希望避免像这样使用class_eval

Here's an explanation of your code: 这是您的代码的解释:

The %{hello} is just another way to write a string literal in Ruby, without having to worry about escaping double or single quotes within the string: %{hello}只是在Ruby中编写字符串文字的另一种方法,而不必担心在字符串中转义双引号或单引号:

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

The val in your code is an argument of the method being defined. 代码中的val是要定义的方法的参数。

The class_eval is used to define some methods by computing the text one would write to do the definition and then evaluating it. class_eval用于通过计算用于执行定义然后对其进行评估的文本来定义一些方法。 It is not necessary here, BTW. BTW,这里没有必要。 An equivalent code would be: 等效代码是:

class Module
  def attr_ (*syms)
    syms.each do |sym|
      define_method "#{sym}=" do |val|
        instance_variable_set "@#{sym}", val
      end
    end
  end
end

This is just equivalent to the builtin attr_writer . 这相当于内置的attr_writer

Update : There can actually be a significant difference between the two... 更新 :两者之间实际上可能存在显着差异......

The class_eval version is vulnerable if you can't trust the argument syms . 如果你不能信任参数syms那么class_eval版本是易受攻击的。 For example: 例如:

class Foo
  attr_ "x; end; puts 'I can execute anything here!'; val=42; begin; val"
end

The class_eval version will print "I can execute anything here" twice, proving it can execute anything. class_eval版本将打印“我可以在这里执行任何操作”两次,证明它可以执行任何操作。 The define_method version won't print anything. define_method版本不会打印任何内容。

This type of code was pivotal to create major vulnerability for all installed Rails apps. 此类代码对于为所有已安装的Rails应用程序创建主要漏洞至关重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM