Ruby中的一切都是动态的,例如,我们可以在程序运行时,动态的添加方法,类等。前面我们已经看到了Ruby的动态特性,例如:给单个对象添加方法,重新打开类等。
如果熟悉Rails,就知道ActiveRecord提供基于数据库表的字段名的方法。每一个字段都有一个方法,这个就依赖于Ruby的动态特性。
一、单例类的位置
我们可以为一个对象定义只属于自己的方法
obj=Object .new def obj.say puts "Hello World " end obj.say #输出 Hello World
那么单例方法定义在哪里呢?Ruby把单例方法定义在单例类(singleton class)中.每一个对象实际上都有两个类:
- 多个实例共享的类
- 单例类
对象调用的方法就是定义在这两个类中的方法,以及祖先类和混含模块中的方法,对象可以调用它所属的类的实例方法,也可以调用单例类中的方法。单例类是匿名的,他们是类对象的实例(Class类的实例),但他们是自动生成且没有名字
str="Hello World " class <<str def bye self +", bye " end end puts str.bye输出 "Hello World, bye"
在方法查找上,单例方法是最先找到的。
二、eval方法
这个和其它很多语言一样,具有在运行时执行以字符串形式保存代码的的功能。
1.直接执行代码
2. 运行时提供方法名的例子
print "Greeting Method: " m=gets .chomp eval ("def #{m};puts 'Hello'; end ") eval (m)输出:Hello
如果输入hi, eval求职的字符串是 def hi; puts 'Hello'; 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 @a=1 end end c=C.new c.instance_eval {puts @a}
五、class_eval
class_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可以访问外围作用域的变量。var="test variable " class C puts var end C.class_eval {puts var}变量var在标准的类定义体的作用域之外,但是在class_eval的代码块的作用域之内
当在class_eval的块中定义一个实例方法时,又有不同var="test " class C end C.class_eval {def hi; puts var; end } c.new.hi # undefined local variable or method `c' for main:Object (NameError)但我们可以使用另外一种方法
C.class_eval {define_method("hi "){ puts var}}
六、Proc对象
pr=Proc .new {puts "Hello from inside of proc block "} pr.call #输出: Hello from inside of proc block
1、做为闭包的Proc对象
Proc对象随身携带了它的上下文,下面上下文包含一个变量a,该变量被赋值为一个特殊的字符串保存在Proc对象中。像这样带着产生它的上下文信息的
一段代码被称为闭包。产生一个闭包就像是打包一件行李:任何时候打开行李,都包含打包进去的东西,在打开一个闭包时(通过调用它), 它包含产生它的时候你放进去的东西。
def call_proc(pr) a="Jack " puts a pr.call end a="Tom " pr=Proc .new {puts a} pr.call call_proc(pr) #输出: Tom # Jack # Tom
2. Proc对象的参数
产生Proc对象时所提供的代码块可以接收参数
pr=Proc .new {|x| puts "#{x} is better man "} pr.call("Jack ") 输出:Jack is better man
七、匿名函数(lambda)
lam=lambda {puts "Hello World "} lam.call 输出: Hello Worldlambda不是Lambda类的对象,他们是Proc类的对象lam.class 输出: Proc和所有的Proc对象一样,lambda是闭包;他们随身携带了生成他们的局部的上下文环境
lambda生成的Proc对象和用Proc.new生成的对象之间的差别与return有关,lambda中的return从lambda返回,而Proc中的return从外围方法返回
def test_return l=lambda {return } l.call puts "I am here " p =Proc .new {return } p .call puts "bye " end test_return 输出: "I am here "
八、再论代码块
可以在方法中吧代码块转换成Proc对象,可以通过参数中最后一个变量,且必须&开头来捕获代码块
def say_block(&block) block.call end say_block {puts "How are you? "} #output: how are you? def test_block(x,y, &block) puts x+y block.call end test_block(1,2) {puts "Hi "} #output: 3 # Hi也可以将Proc对象或lambda转换为代码块def say_block(&block) block.call end lam=lambda {puts "Hello world "} say_block(&lam) #output: Hello world
本文作者:王德水
发表评论
-
一步一步学Ruby(十九): Hash
2009-05-06 09:39 1228一、Hash的定义和赋值 Hash代表键值对的集合,Ru ... -
一步一步学Ruby(十八):数组
2009-05-06 09:39 1019一、数组定义和基本操作 1. 数组的定义和其它 ... -
一步一步学Ruby(十六):符号
2009-05-06 09:34 1001一、符号的定义 符号是Ruby内建类Symbol的实例, ... -
一步一步学Ruby(十五):错误处理和异常
2009-05-06 09:33 1002一、常见异常 异常名 常见原因 怎样抛出 ... -
一步一步学Ruby(十四): self和作用域
2009-05-06 09:32 1176一、默认对象或当前对象是self 为了知道哪个对象是当前 ... -
一步一步学Ruby(十三):Ruby模块
2009-05-06 09:31 1206Class类是Module的子类,类是一种特殊形式的模块,这个 ... -
一步一步学Ruby(十二):Ruby类
2009-05-06 09:30 1070一、类的定义、类的实例方法 二、特定对象的方法 ... -
一步一步学Ruby(十一):控制语句
2009-05-06 09:14 989一、比较语句 大部分和其他的语言一样,这里注意<= ... -
一步一步学Ruby(十):Ruby正则表达式(下)
2009-05-06 09:08 2832本文内容: 贪婪量词和不贪婪量词 锚 前视断言 ... -
一步一步学Ruby(九):Ruby正则表达式(上)
2009-05-06 09:04 1273先推荐一个在线的Ruby正 ... -
一步一步学Ruby(八):字符串表达式
2009-05-06 09:03 1257Ruby中,内置很多对字符串操作的方法,下面我们看看最主要的一 ... -
一步一步学Ruby(七):数学表达式
2009-05-06 09:02 918我们知道,在计算机的最底层,是完全基于数据的,我们编写程序,就 ... -
一步一步学Ruby(六):方法定义及调用
2009-05-06 09:01 849一、方法定义 过程式方法 Ruby虽 ... -
一步一步学Ruby(五): Class, Module, Object,Kernel的关系
2009-05-06 09:01 12471. Class, Module, Object,Kernel ... -
一步一步学Ruby(四):Ruby标准类型
2009-05-06 09:00 1015Ruby 的标准类型包括数字(Numeric)、字符串(Str ... -
一步一步学Ruby(三): Ruby代码注释
2009-05-06 08:59 2187本文内容 单行注释 多行注释 特殊处理 ... -
一步一步学Ruby(二):变量,常量
2009-05-06 08:57 1236本文内容 变量 变量范围 伪变量 常量 ... -
一步一步学Ruby(一): Ruby介绍
2009-05-06 08:56 1587文章摘要 Ruby是如何来的 准备 ...
相关推荐
松本行弘在设计Ruby时,融合了多种他所喜爱的语言特性,包括**Perl**、**Smalltalk**、**Eiffel**、**Ada**和**Lisp**,从而创造出一种结合了函数式和过程式编程特性的独特语言。他的目标是使Ruby既自然又强大,即使...
### Ruby on Rails Guides v2 - Ruby on Rails 4.2.5 #### 一、重要概念及基础假设 - **重要概念**:本指南旨在帮助读者深入理解Ruby on Rails(以下简称Rails)4.2.5版本的核心功能与最佳实践。 - **基础假设**:...
- **Ruby**:相比之下,Ruby 是一种动态类型的脚本语言,它的语法更加灵活,支持多种编程范式(包括面向对象和函数式编程)。Ruby 代码通常更简洁、易于阅读。 2. **生产力与开发效率**: - **Java**:虽然 Java ...
4. **闭包和上下文**:理解块、Proc和Lambda如何捕获并保留其定义时的上下文,是掌握Ruby高级特性的重要一步。 5. **元编程**:Ruby允许在运行时修改自身,这被称为元编程。例如,你可以动态添加方法、修改类的行为...
Ruby是一种面向对象的、动态类型的脚本语言,以其简洁明了的语法和强大的元编程能力著称,这使得它成为开发复杂逻辑应用的理想选择,比如棋类游戏。 在Ruby-chess项目中,每个棋子被表示为一个对象,它们有自己的...
Ruby是一种动态的、面向对象的解释型编程语言,因其简洁易读的语法和强大的库支持而在Web开发领域中备受青睐。开发Ruby应用的第一步是搭建合适的开发环境。推荐使用macOS或Linux作为首选操作系统,因为这些系统通常...
- **利用元编程**:利用 Ruby 的元编程能力,如模块混合(mixins)、动态方法定义等特性进行重构。 - **利用动态类型**:通过动态地修改类和对象来优化代码结构。 - **利用代码块和迭代器**:利用 Ruby 强大的迭代器...
Ruby是一种面向对象、动态类型的编程语言,由日本的松本行弘在1995年设计并开发。它强调简洁、优雅的语法,注重程序员的生产力,并提供了丰富的库和工具支持。Ruby-2.3.0是Ruby的一个版本,发布于2016年,带来了许多...
从早期的机器语言到汇编语言,再到高级语言如C、C++、Java,以及动态语言如Python、Ruby,每一步都标志着计算机科学的进步。了解这一历史脉络有助于学习者更好地把握Ruby语言在当前编程生态中的位置及其独特价值。 ...
Ruby是一种面向对象、动态类型的编程语言,以其简洁的语法和强大的功能深受开发者喜爱。Scite,全称SciTE( Scientific ...在深入学习Ruby编程的同时,掌握Scite的各种特性和设置,无疑会成为提升开发技能的重要一步。
Ruby是一种动态、反射、面向对象、通用的编程语言,由松本行弘(Yukihiro "Matz" Matsumoto)在1993年推出,并在1995年左右首次公开。Ruby语言的设计哲学强调简洁和高效,它采用了一种称为“最小惊讶”原则...
Ruby作为一种灵活且强大的编程语言,具有以下显著特性: - **面向对象**:一切皆对象,包括基本的数据类型。 - **动态类型**:无需提前声明变量类型,增加了语言的灵活性。 - **简洁的语法**:Ruby的语法简洁明了,...
Ruby-2.5.0是Ruby编程语言的一个版本,它在2018年发布,带来了许多性能优化和新特性。这个`.tar.gz`文件是一个压缩包,它包含Ruby 2.5.0的所有源代码文件,适用于在CentOS 6.5上安装Redmine时使用。Redmine是一款...
在Ruby-2.2.5这个版本中,有以下几个重要的改进和特性: - **性能提升**:相比于之前的版本,Ruby-2.2.5在运行速度上有所优化,提高了程序执行效率。 - **更好的垃圾回收机制**:改进了垃圾回收算法,减少了内存...
3. 运行`ruby extconf.rb`来生成Makefile,这一步会根据当前的Ruby环境配置编译选项。 4. 接着运行`make`来编译C扩展。 5. 最后,运行`sudo make install`将编译好的扩展安装到Ruby的扩展目录。 在使用Ruby-FCGI时...
Ruby是一种高级、动态的、面向对象的编程语言,它的设计理念在于提供简单且高效的编程体验。Ruby以其简洁的语法和强大的面向对象特性而受到开发者的喜爱。作为解释型语言,Ruby代码可以直接执行,无需预编译步骤,这...
标题 "24_ruby_algorithm_" 暗示我们要讨论的是使用 Ruby 编程语言实现解决数学游戏“24点”的算法。在这个经典游戏中,玩家...通过对 `24.rb` 文件的分析和学习,开发者可以加深对 Ruby 语言特性和算法设计的理解。
Ruby是一种面向对象的编程语言,以其简洁和强大的语法特性而受到开发者喜爱。在Ruby中,数组是一种非常重要的数据结构,用于存储一系列有序的元素,这些元素可以是任意类型,包括整数、浮点数、字符串、布尔值甚至是...
Ruby是一种动态类型、面向对象的脚本语言,其语法简洁优雅,特别适合快速开发和原型设计。在这篇知识总结中,我们将深入探讨Ruby中的线程同步和闭包(包括Blocks、Procs、Lambdas和Methods)。 首先,让我们关注...
通过这个项目,开发者不仅能深入理解Ruby的基本语法和特性,还能锻炼到问题解决、算法设计以及代码组织等高级编程技巧。在实际操作中,你可能还需要学习如何使用版本控制工具如Git,以及如何编写清晰的文档,以便...