ruby中的instance_eval,class_eval,eval
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关键字不能做的事
- 在类定义的上下文中对字符串求值
- 为匿名类(但不包含单例类)打开类定义(也就是说在不知道类的名字的情况就打开一个类)
- 获取外围作用域中变量的访问权
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的更多相关文章
- ruby中的链式访问和方法嵌套
先看一道题,这道题是codewars上的一道题,我很早就看到了,但是不会写.等到又看到这道题的时候,我刚看完元编程那本书,觉得是可以搞定它的时候了.废话不多说,先看这道题,题目最开始是为JavaScr ...
- 谈谈Ruby中的类变量
Ruby中的类变量,很多文章都是不太建议使用的,主要原因在于他的一些特性容易导致犯一些错误,尤其在广泛使用元编程的时候. 初步接触类变量可能觉得他跟C++的类静态成员和Java中的静态变量没什么区别, ...
- [翻译]理解Ruby中的blocks,Procs和lambda
原文出处:Understanding Ruby Blocks, Procs and Lambdas blocks,Procs和lambda(在编程领域被称为闭包)是Ruby中很强大的特性,也是最容易引 ...
- 浅谈AngularJS中的$parse和$eval
AngularJS的初学者常常会对$parse和$eval两个内建服务感到有些困惑,今天我们就来说说AngularJS中的$parse和$eval. 总的来说,$parse和$eval都是作用于Ang ...
- 理解Ruby中的作用域
作用域对于Ruby以及其它编程语言都是一个需要理解的至关重要的基础知识.在我刚开始学习ruby的时候遇到很多诸如变量未定义.变量没有正确赋值之类的问题,归根结底是因为自己对于ruby作用域的了解不够, ...
- [No000010]Ruby 中一些百分号(%)的用法小结
#Ruby 中一些百分号(%)的用法小结 #这篇文章主要介绍了Ruby 中一些百分号(%)的用法小结,需要的朋友可以参考下 what_frank_said = "Hello!"#% ...
- Ruby中 使用Builder Xml Markup 操作XML
=begin Ruby中 使用Xml Markup 轻松的对XML文档操作, 项目地址:http://builder.rubyforge.org/ 使用之前我们需要安装Builder xml mark ...
- Ruby中Block, Proc, 和Lambda
Block Blocks就是存放一些可以被执行的代码的块,通常用do...end 或者 {}表示 例如: [1, 2, 3].each do |num| puts num end [1, 2, 3]. ...
- ruby中symbol
Symbol 是什么 Ruby 是一个强大的面向对象脚本语言(本文所用 Ruby 版本为1.8.6),在 Ruby 中 Symbol 表示“名字”,比如字符串的名字,标识符的名字. 创建一个 Symb ...
随机推荐
- 【Python】用文本打印树
From:http://zhidao.baidu.com/link?url=O8U5TynGBMojDw2iFhlghPPf5_ZE1X8CAQMrK19pv-KxhvKCc6Z2yzsoQaukgN ...
- expected_conditions判断页面元素
expected_condtions提供了16种判断页面元素的方法: 1.title_is:判断当前页面的title是否完全等于预期字符串,返回布尔值 2.title_contains:判断当前页面的 ...
- A mail sent to Google chromium.org Groups for Help
Hi, I've ported Chromium M39 to 4.4 using WebView. The main modifications are: I changed AwContents: ...
- C++ 访问控制 public, protected, private, 友元
1. 变量属性与继承之间的关系 #include <iostream> using namespace std; class A { public: int x; protected: i ...
- Python学习笔记4—列表List
列表定义 Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. >>> a=['] >>> type(a) &l ...
- Linux产生随机数的几种常见方法
方法1: [root@localhost ~]# echo $RANDOM 方法二 [root@localhost ~]# openssl rand -base64 7X6HMer5hhY= 方法三 ...
- Shell脚本编程与文件系统修复
导读 Linux基金会发起了LFCS认证(Linux 基金会认证系统管理员)Linux Foundation Certified Sysadmin,这是一个全新的认证体系,旨在让世界各地的人能够参与到 ...
- 微软笔试题-highways
题目大意 一条单向的高速公路上有N辆车,在0时刻,每辆车分别在起点A[0],A[1]....处开始从北向南出发,每辆车有个终点B[0],B[1]....且每辆车有个限制速度 V[0],V[1]... ...
- 160425、linux安装SVN服务器
1:查看linux是否已经安装svn服务 [root@nb ~]# rpm -qa subversion subversion-1.6.11-15.el6_7.x86_64 2:安装svn #yum ...
- Hadoop 启动脚本分析与实战经验
start-all.sh脚本现在已经废弃,推荐使用start-dfs.sh和start-yarn.sh分别启动HDFS和YARN. 在新一代的Hadoop里面HDFS称为了统一存储的平台,而YARN成 ...