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的任意实例都可以调用该方法。
分享到:
相关推荐
`define_method`和`class_eval`是Ruby元编程中的两个关键方法,它们被广泛用于动态地添加方法到类或者模块中。这篇文章将深入探讨这两个方法的用法和区别。 `define_method`方法允许我们传递一个符号和一个代码块来...
Ruby是一种动态、开源的编程语言,以其简洁、优雅的语法和强大的元编程能力著称。在Ruby开发中,为了管理不同版本的Ruby环境,我们常常会使用到`rbenv`和`ruby-build`这两个工具。本文将详细介绍如何使用`ruby-build...
3. **动态性**:Ruby的动态性体现在运行时可以改变类、方法和变量的定义,允许动态绑定和鸭子类型。这为开发过程提供了极大的灵活性,但同时也要求开发者具备更高的责任感。 4. **块、 Proc 和 Lambda**:Ruby中的...
《ruby23-language.chm》文档深入讲解了Ruby语言的特性,如动态性、元编程、闭包和块、方法定义与调用、变量作用域等。Ruby允许在运行时修改代码,这使得元编程成为其强大之处。理解如何使用`eval`、`class_eval`和`...
2. **动态性**:Ruby支持动态类型,变量的类型在运行时确定,无需提前声明。此外,它允许在程序运行时修改类和方法,增加了灵活性。 3. **元编程**:Ruby的元编程能力非常强大,可以使用`class_eval`、`instance_...
Ruby元编程是编程领域中一个深入且强大的主题,它允许程序员在运行时修改或创建代码,极大地提高了灵活性和代码的动态性。这本书“Ruby元编程第二版”专注于讲解Ruby语言的这一独特特性,旨在帮助开发者更好地理解和...
Ruby元编程的核心概念包括类、模块、方法、变量和对象的动态性。以下是对这些概念的详细解释: 1. **类与模块**:在Ruby中,类和模块都是对象。你可以动态地创建和修改它们。例如,你可以通过`Class.new`创建一个新...
2. 动态性:Ruby是一种动态类型语言,变量的类型在运行时确定,允许灵活的编程风格。 3. 元编程:Ruby提供了丰富的元编程工具,如`eval`、`send`和`class_eval`等,使代码可以在运行时修改自身,增强了代码的灵活性...
Ruby是一种动态类型的面向对象语言,它的灵活性和简洁性使得它非常适合进行元编程。元编程是指编写能够生成或操纵其他代码的程序的技术。在Ruby中,元编程是一项非常强大的特性,可以让开发者以更加灵活的方式构建...
2. **动态性**:Ruby支持动态类型,这意味着变量的类型在运行时确定,无需预先声明。它还允许动态地修改或添加类的方法和属性。 3. **块、迭代器和闭包**:Ruby中的块是代码段,可以与方法配合使用,通过`do..end`...
- **动态性**:Ruby是一种动态类型语言,这意味着可以在运行时修改类和对象。 - **灵活性**:Ruby提供了丰富的API来支持元编程,如`eval`, `instance_eval`, `class_eval`等方法,使得在程序运行过程中动态地创建和...
Ruby是一种面向对象的、动态的、灵活的编程语言,以其简洁的语法和强大的元编程能力著称。Ruby API文档主要包含了Ruby标准库、核心库以及语言本身的函数和类的详细说明。以下是这些文件的主要内容: 1. **ruby19-...
- **元编程**:Ruby提供了`eval`、`define_method`等方法,允许在运行时修改或创建类和方法,增强了灵活性。 - **异常处理**:通过`begin..rescue..end`结构处理程序中的异常情况。 3. **Ruby-2.5系列的特性**:...
2. **动态性**:Ruby 1.8.6 支持动态类型,变量无需预先声明类型,它们的类型在运行时自动确定。这种灵活性允许程序员快速迭代和调试代码。 3. **块和迭代器**:Ruby 中的块(blocks)是通过 `do..end` 或 `{..}` ...
在Ruby这种动态编程语言中,元编程是一种核心技术,它不仅仅是一种技巧,更是Ruby和Rails框架中用于提高开发效率和软件复用性的关键方法。 在Ruby语言中,元编程主要通过方法拦截、动态方法定义、元类以及一些特殊...
Ruby作为一种动态、面向对象的编程语言,以其简洁、优雅的语法和强大的元编程能力赢得了全球开发者群体的喜爱。这本书的中文版第二版是对原英文版的更新和升级,旨在帮助中文读者更好地理解和运用Ruby。 Ruby的核心...
- 动态性:Ruby允许在运行时修改类和对象,比如添加方法、改变属性等,这是元编程的基础。 - `send`方法:通过`send`方法,可以动态地调用对象的方法,甚至包括私有方法。 - `eval`和`instance_eval`:`eval`可以...
6. **评估(Evaluation)**:Ruby的`eval`函数允许程序执行字符串形式的代码,这可以用来构建动态的代码生成器或解释器。虽然`eval`的使用需要谨慎以避免安全问题,但它仍然是元编程中一个重要的工具。 7. **代码生成...
这种灵活性使得Ruby在编写DSL(领域特定语言)时特别得心应手。 本书可能涵盖了Ruby的标准库,这是Ruby内置的一系列模块和类,包含各种实用功能,如文件操作、网络通信、日期时间处理等。通过学习标准库,开发者...