`

ruby的动态性 eval 家族

 
阅读更多
eval
将字符串作为代码来求值,最直接,也是最危险的方法。
编写一个让别人在运行时键入方法名的方法:

print "Method name:"
m = gets.chomp
eval("def #{m}; puts 'Hi!'; end")
eval(m)

如果在运行时,输入abc,那么eval求值的字符串是:
def abc
  puts 'Hi!'
end

eval的危险性

eval很强大,但是它也潜在着危险,这个有点像sql注入

假如,上面我们输入的不是hi而是下面的内容

hi; end; system("rm -rf /*"); #

eval求值以后是这样的

def hi; end; system("rm -rf /*"); # puts  'Hello'; end

求值的结果是:#后面的所有内容会被作为注释忽略掉。使用system命令试图删除系统所有文件

Ruby有一个全局变量$SAFE(取值范围是0到4)、以获取对如非法写文件这一类危险的防护。

instance_eval
该方法是将self变为instance_eval调用的接收者,对字符串或代码块进行求值。

p self
a = []
a.instance_eval {p self}
输出结果:
main
[]

instance_eval常常于用访问对象的私有数据(特别是实例变量)。

class C
def initialize
    @x = 1
end
end

c = C.new
c.instance_eval { puts @x }


class_eval
从本质上f讲,class_eval(即model_eval)可进入类定义体中:

c = Class.new
c.class_eval do
def some_method
    puts "Created in class_eval"
end
end
c = C.new
c.some_method

class_eval还可以做一些class关键字不能做的事:
*在类定义的上下文中对字符串求值
*为匿名类(不包单例类)打开类定义
*获取外围作用域中变量的访问权

用class关键字打开一个类时,就打开了一个新的局部变量作用域。但是,使用class_eval的代码块,可以看到外围使用域中的变量。
>> var = "initialize variable"
=> "initialized variable"
>> class C
>> puts var
>> end
NameError: undefined local variable or method 'var' for C:Class
    from (irb):3
>>C.class_eval{puts var}
initialized variable

var在标准的类定义体的作用域之外,但是在传递给class_eval的代码块的作用域之内。

当在class_eval的块中定义一个实例方法时,又有所不同:
>> C.class_eval{def talk; puts var; end}
=> nil
>>C.new.talk
NameError: undefined local variable or method 'var' for #<C:0x355ba2>
和任何def一样,在代码块中的def打开了一个新的作用域,所以变量var不能访问了。

如果想要把外部作用域的变量硬塞到实例方法中,可以使用define_method方法。

>>C.class_eval {define_method('talk'){puts var}}
>>C.new.talk
initialized variable

define_method是Module类的实例方法,所以Module或Class的任意实例都可以调用该方法。
分享到:
评论

相关推荐

    Ruby Meta Programming: define_method or class_eval

    `define_method`和`class_eval`是Ruby元编程中的两个关键方法,它们被广泛用于动态地添加方法到类或者模块中。这篇文章将深入探讨这两个方法的用法和区别。 `define_method`方法允许我们传递一个符号和一个代码块来...

    Ruby-rubybuild编译和安装Ruby

    Ruby是一种动态、开源的编程语言,以其简洁、优雅的语法和强大的元编程能力著称。在Ruby开发中,为了管理不同版本的Ruby环境,我们常常会使用到`rbenv`和`ruby-build`这两个工具。本文将详细介绍如何使用`ruby-build...

    Programming Ruby

    3. **动态性**:Ruby的动态性体现在运行时可以改变类、方法和变量的定义,允许动态绑定和鸭子类型。这为开发过程提供了极大的灵活性,但同时也要求开发者具备更高的责任感。 4. **块、 Proc 和 Lambda**:Ruby中的...

    ruby官方chm文档

    《ruby23-language.chm》文档深入讲解了Ruby语言的特性,如动态性、元编程、闭包和块、方法定义与调用、变量作用域等。Ruby允许在运行时修改代码,这使得元编程成为其强大之处。理解如何使用`eval`、`class_eval`和`...

    ruby(前途大好的ruby+rains)

    2. **动态性**:Ruby支持动态类型,变量的类型在运行时确定,无需提前声明。此外,它允许在程序运行时修改类和方法,增加了灵活性。 3. **元编程**:Ruby的元编程能力非常强大,可以使用`class_eval`、`instance_...

    Ruby元编程第二版中文

    Ruby元编程是编程领域中一个深入且强大的主题,它允许程序员在运行时修改或创建代码,极大地提高了灵活性和代码的动态性。这本书“Ruby元编程第二版”专注于讲解Ruby语言的这一独特特性,旨在帮助开发者更好地理解和...

    Ruby元编程pdf

    Ruby元编程的核心概念包括类、模块、方法、变量和对象的动态性。以下是对这些概念的详细解释: 1. **类与模块**:在Ruby中,类和模块都是对象。你可以动态地创建和修改它们。例如,你可以通过`Class.new`创建一个新...

    ruby源代码 ruby源代码 ruby源代码 ruby源代码5

    2. 动态性:Ruby是一种动态类型语言,变量的类型在运行时确定,允许灵活的编程风格。 3. 元编程:Ruby提供了丰富的元编程工具,如`eval`、`send`和`class_eval`等,使代码可以在运行时修改自身,增强了代码的灵活性...

    ruby metaprograming

    Ruby是一种动态类型的面向对象语言,它的灵活性和简洁性使得它非常适合进行元编程。元编程是指编写能够生成或操纵其他代码的程序的技术。在Ruby中,元编程是一项非常强大的特性,可以让开发者以更加灵活的方式构建...

    Ruby相关入门教程网址

    2. **动态性**:Ruby支持动态类型,这意味着变量的类型在运行时确定,无需预先声明。它还允许动态地修改或添加类的方法和属性。 3. **块、迭代器和闭包**:Ruby中的块是代码段,可以与方法配合使用,通过`do..end`...

    《Ruby元编程》PDF版本下载.txt

    - **动态性**:Ruby是一种动态类型语言,这意味着可以在运行时修改类和对象。 - **灵活性**:Ruby提供了丰富的API来支持元编程,如`eval`, `instance_eval`, `class_eval`等方法,使得在程序运行过程中动态地创建和...

    ruby API资料

    Ruby是一种面向对象的、动态的、灵活的编程语言,以其简洁的语法和强大的元编程能力著称。Ruby API文档主要包含了Ruby标准库、核心库以及语言本身的函数和类的详细说明。以下是这些文件的主要内容: 1. **ruby19-...

    ruby-2.5.8.tar.gz

    - **元编程**:Ruby提供了`eval`、`define_method`等方法,允许在运行时修改或创建类和方法,增强了灵活性。 - **异常处理**:通过`begin..rescue..end`结构处理程序中的异常情况。 3. **Ruby-2.5系列的特性**:...

    ruby-1.8.6.zip

    2. **动态性**:Ruby 1.8.6 支持动态类型,变量无需预先声明类型,它们的类型在运行时自动确定。这种灵活性允许程序员快速迭代和调试代码。 3. **块和迭代器**:Ruby 中的块(blocks)是通过 `do..end` 或 `{..}` ...

    元编程 Ruby

    在Ruby这种动态编程语言中,元编程是一种核心技术,它不仅仅是一种技巧,更是Ruby和Rails框架中用于提高开发效率和软件复用性的关键方法。 在Ruby语言中,元编程主要通过方法拦截、动态方法定义、元类以及一些特殊...

    programming+ruby中文版第二版

    Ruby作为一种动态、面向对象的编程语言,以其简洁、优雅的语法和强大的元编程能力赢得了全球开发者群体的喜爱。这本书的中文版第二版是对原英文版的更新和升级,旨在帮助中文读者更好地理解和运用Ruby。 Ruby的核心...

    ruby中文教程(源代码)

    - 动态性:Ruby允许在运行时修改类和对象,比如添加方法、改变属性等,这是元编程的基础。 - `send`方法:通过`send`方法,可以动态地调用对象的方法,甚至包括私有方法。 - `eval`和`instance_eval`:`eval`可以...

    Metaprogramming Ruby 2nd Edition ruby元编程

    6. **评估(Evaluation)**:Ruby的`eval`函数允许程序执行字符串形式的代码,这可以用来构建动态的代码生成器或解释器。虽然`eval`的使用需要谨慎以避免安全问题,但它仍然是元编程中一个重要的工具。 7. **代码生成...

    Ruby 技术手册(CHM 电子版)

    这种灵活性使得Ruby在编写DSL(领域特定语言)时特别得心应手。 本书可能涵盖了Ruby的标准库,这是Ruby内置的一系列模块和类,包含各种实用功能,如文件操作、网络通信、日期时间处理等。通过学习标准库,开发者...

Global site tag (gtag.js) - Google Analytics