ruby具有在运行时执行以字符串形式保存的代码的功能设施,eval族方法 。包括Kernel#eval,Object#instance_eval,Module#class_eval。

  Kernel#eval

  它是最直接的方法

如下:

 p eval("2+2")

 eval("def m;p 'hello world';end")
eval("m")

输出

4
"hello world"

  eval强大而危险,有代码注入之类的危险,尽管ruby中有一个全局变量$SAFE来控制它,但最好还是不要用它。

  Object#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}

输出

1

  instance_eval也可以接受字符串,访问局部变量。

如下:

 arr = ['a','b','c']
ch = 'd'
arr.instance_eval "self[1] = ch"
p arr

输出

["a", "d", "c"]

  

  instance_eval中定义方法,则会是个单例方法

如下: 

 obj = Object.new

 obj.instance_eval do
def method
p "hello world"
end
end
p obj.singleton_methods

输出

[:method]

  Module#class_eval

  class_eval和module_eval是一样的。它可以进入类定义体内。

 C = Class.new
C.class_eval do
def method
p "hello world"
end
end
c = C.new
c.method

输出

"hello world"

  

  class_eval可以做一些class关键字不能做的事

  1. 在类定义的上下文中对字符串求值
  2. 为匿名类(但不包含单例类)打开类定义(也就是说在不知道类的名字的情况就打开一个类)
  3. 获取外围作用域中变量的访问权
 def add_method_to(a_class)
a_class.class_eval do
def method ; p "hello world";end
end
end
add_method_to String
"abc".method

输出

"hello world"

 var = "hello world"

 class C
end
C.instance_eval {puts var}

输出

"hello world"

  

  总结:instance_eval()方法仅仅会改变self ,而 class_eval()会同时修改self和当前类,通过修改当前类,class_eval()实际上是重新打开了该类,就像class关键字一样。

  Module#class_eval()比class关键字更加灵活,class关键字只能使用常量,而class_eval()可以对任何代表类的变量使用class_eval()方法。class会打开一个新的作用域,但是class_eval()其实是扁平化作用域。

ruby中的instance_eval,class_eval,eval的更多相关文章

  1. ruby中的链式访问和方法嵌套

    先看一道题,这道题是codewars上的一道题,我很早就看到了,但是不会写.等到又看到这道题的时候,我刚看完元编程那本书,觉得是可以搞定它的时候了.废话不多说,先看这道题,题目最开始是为JavaScr ...

  2. 谈谈Ruby中的类变量

    Ruby中的类变量,很多文章都是不太建议使用的,主要原因在于他的一些特性容易导致犯一些错误,尤其在广泛使用元编程的时候. 初步接触类变量可能觉得他跟C++的类静态成员和Java中的静态变量没什么区别, ...

  3. [翻译]理解Ruby中的blocks,Procs和lambda

    原文出处:Understanding Ruby Blocks, Procs and Lambdas blocks,Procs和lambda(在编程领域被称为闭包)是Ruby中很强大的特性,也是最容易引 ...

  4. 浅谈AngularJS中的$parse和$eval

    AngularJS的初学者常常会对$parse和$eval两个内建服务感到有些困惑,今天我们就来说说AngularJS中的$parse和$eval. 总的来说,$parse和$eval都是作用于Ang ...

  5. 理解Ruby中的作用域

    作用域对于Ruby以及其它编程语言都是一个需要理解的至关重要的基础知识.在我刚开始学习ruby的时候遇到很多诸如变量未定义.变量没有正确赋值之类的问题,归根结底是因为自己对于ruby作用域的了解不够, ...

  6. [No000010]Ruby 中一些百分号(%)的用法小结

    #Ruby 中一些百分号(%)的用法小结 #这篇文章主要介绍了Ruby 中一些百分号(%)的用法小结,需要的朋友可以参考下 what_frank_said = "Hello!"#% ...

  7. Ruby中 使用Builder Xml Markup 操作XML

    =begin Ruby中 使用Xml Markup 轻松的对XML文档操作, 项目地址:http://builder.rubyforge.org/ 使用之前我们需要安装Builder xml mark ...

  8. Ruby中Block, Proc, 和Lambda

    Block Blocks就是存放一些可以被执行的代码的块,通常用do...end 或者 {}表示 例如: [1, 2, 3].each do |num| puts num end [1, 2, 3]. ...

  9. ruby中symbol

    Symbol 是什么 Ruby 是一个强大的面向对象脚本语言(本文所用 Ruby 版本为1.8.6),在 Ruby 中 Symbol 表示“名字”,比如字符串的名字,标识符的名字. 创建一个 Symb ...

随机推荐

  1. No JSON object could be decoded

    json中的true 不能写成True,否则不能被解析.

  2. Java去除所有非中文字符串

    "fdsfjasd阿斯顿飞机阿斯蒂芬,,,,,,,,....".replaceAll("[^\u4E00-\u9FA5]", "");

  3. JBPM4 经常使用表结构及其说明

    首先我想说.这不一篇原创博文. 这里设置成原创.主要是为了分享,由于它对于jbpm的刚開始学习的人,真的值得一看.原作者的博文地址并没有查到,我是在还有一位转载此文的博主那儿获得的.地址在这儿. 本文 ...

  4. jquery书写一个简易的二级联动

    先用php生成一个json数组示例如下 JSON_UNESCAPED_UNICODE 是对汉字进行处理的参数 然后HTML代码如下 把那个json_city赋值成我们用php生成的json即可 < ...

  5. laravel 调试模式及日志配置

    1)调试模式和日志的配置都在 config/app.php 配置文件中 2)打开调试模式 'debug' => env('APP_DEBUG', true) 3)laravel的日志默认已经打开 ...

  6. 第二十一篇:Linux 操作系统中的进程结构

    前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系.依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 ...

  7. phpcms 列表页中调用其下的所有子栏目(或特定的子栏目)的方法

    phpcms 列表页中,如何调用其下的所有子栏目(或特定的子栏目),具体的写法如下,感兴趣的朋友可以参考下,希望对大家有所帮助 代码如下: {pc:get sql="select * fro ...

  8. [Web] 如何实现Web服务器和应用服务器的负载均衡?

    本文对Web服务器和应用服务器的负载均衡进行说明. 在负载均衡的思路下,多台服务器为对称方式,每台服务器都具有同等的地位,可以单独对外提供服务而无须其他服务器的辅助.通过负载分担技术,将外部发送来的请 ...

  9. [Domino]从嵌入另一个数据库嵌入的Embedded View无法正常显示,提示unable to lauch

    发现问题 1. 项目中需要在一个数据库中插入另一个数据库的Embedded View,使用起来十分费劲,在选择数据库的下拉菜单中经常会找不到目标数据库: 2. 在做日文版的时候,从workbench导 ...

  10. spring boot 加载jsp

    1.spring boot启动类继承SpringBootServletInitializer ,并且重写configure方法 package com.springapp.mvc;import jav ...