如何使用class_eval? [英] How do I use class_eval?

查看:105
本文介绍了如何使用class_eval?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不理解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 避免.

The short answer is: you probably want to avoid using class_eval like this.

以下是您的代码的说明:

Here's an explanation of your code:

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

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 "world"} == "hello \"world\""  # => true

代码中的val是所定义方法的参数.

The val in your code is an argument of the method being defined.

class_eval用于定义一些方法,方法是计算将要编写的文本以编写定义,然后对其求值.顺便说一句,这里没有必要.等效的代码为:

The class_eval is used to define some methods by computing the text one would write to do the definition and then evaluating it. It is not necessary here, 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

这等效于内置的attr_writer.

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

Update: There can actually be a significant difference between the two...

如果您不信任参数syms,则class_eval版本很容易受到攻击.例如:

The class_eval version is vulnerable if you can't trust the argument syms. For example:

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

class_eval版本将打印两次我可以在这里执行任何操作",证明它可以执行任何操作. define_method版本不会打印任何内容.

The class_eval version will print "I can execute anything here" twice, proving it can execute anything. The define_method version won't print anything.

代码类型对于创建主要漏洞用于所有已安装的Rails应用.

This type of code was pivotal to create major vulnerability for all installed Rails apps.

这篇关于如何使用class_eval?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆