2013年5月11日

摘要: 如果你想重构某个类中的某个方法的名字,可是又不想影响已经调用该方法的其他代码,该如何处理呢?可以使用“类宏”技术,请看下面的代码: class MyClass def old_method(name) puts "hello " + name end def new_method(name) puts "hello " + name end def self.deprecate(old_method, new_method) define_method(old_method) do |*args, &block| warn "Warni 阅读全文
posted @ 2013-05-11 16:29 巴晓鹏 阅读(903) 评论(0) 推荐(1) 编辑

2013年5月5日

摘要: 在一些语言中,比如java或C#,有内部作用域(inner scope)的概念。在内部作用域可以看到外部作用域(outer scope)中的变量。但ruby中没有这种嵌套式作用域的概念,它的作用域是截然分开的,一旦进入一个新的作用域,原先的绑定就会被替代为一组新的绑定。在ruby中,程序会在三个地方关闭前一个作用域,同时打开一个新的作用域:类定义、模块定义、方法。只要程序进入类、模块或者方法的定义,就会发生作用域切换。这三个边界分别用class,module和def关键字作为标志,每一个关键字都充当了一个作用域门(scope gate)。怎样让绑定穿越一个作用域门呢?比如下面的代码:my_va 阅读全文
posted @ 2013-05-05 08:28 巴晓鹏 阅读(1158) 评论(0) 推荐(2) 编辑

2013年5月4日

摘要: 从底层来看,使用【块】需要分两步,第一步,将代码打包备用;第二步,调用【块】(通过yield语句)来执行代码。这种“先打包代码,以后调用”的机制并不是【块】的专利。在ruby中,至少还有以下三种方法可以用来打包的代码。1、 使用proc,proc基本上就是一个由块转换成的对象;2、 使用lambda,它是proc的近亲;3、 使用方法。本文将重点讨论proc与lambda的区别。proc与lambda之间有两个主要区别,第一个区别与return关键字有关,第二个区别与参数校验有关。区别之一:return在lambda中,returen是指从lambda对象返回;def add(lam) l.. 阅读全文
posted @ 2013-05-04 11:17 巴晓鹏 阅读(2431) 评论(0) 推荐(2) 编辑

2013年5月3日

摘要: 先看代码:class Fixnum < Integer def fib a = [1,1]; 2.upto(self-1){|i| a[i] = a[i-1] + a[i-2]}; a end end puts 11.fib.to_s输出结果: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]下面解释代码的含义:首先使用【打开类】技术,打开已有的Fixnum类,添加一个名为fib的方法,这样所有的Fixnum对象,比如1,2,3等数字都自动拥有了fib方法。方法第一行先定义一个数组,初始化两个数字【1,1】方法第二行,是一个循环... 阅读全文
posted @ 2013-05-03 08:10 巴晓鹏 阅读(401) 评论(0) 推荐(1) 编辑

2013年5月2日

摘要: 可以利用Module#define_method()方法定义一个方法,只需要为其提供一个方法名和一个充当方法主体的块即可,示例代码如下:class MyClass define_method :my_method do |my_arg| my_arg * 3 endendobj = MyClass.newobj.my_method(2) #=> 6 阅读全文
posted @ 2013-05-02 09:26 巴晓鹏 阅读(238) 评论(0) 推荐(0) 编辑

2013年4月30日

摘要: 在ruby中,编译器并不强制方法调用时的行为,这意味着你可以调用一个并不存在的方法。例如:class Lawyer;endnick = Lawyer.newnick.talk_simpleNoMethodError: undefined method ‘talk_simple’ ……当调用talk_simple()方法时,ruby会到nick对象的类中查询它的实例方法,如果找不到,ruby会沿着祖先链向上搜寻进入Object类,并最终来到Kernel模块。由于ruby没有找到talk_simple()方法,ruby只好承认自己失败了,并在nick对象(最初的接收者)上调用一个名为method_ 阅读全文
posted @ 2013-04-30 22:02 巴晓鹏 阅读(1166) 评论(2) 推荐(0) 编辑
 
摘要: 当你调用一个方法时,通常会使用点(。)标记符,代码如下:class MyClass def my_method(my_arg) my_arg * 2 endendobj = MyClass.newobj.my_method(3) #=>6用Object#send()方法可以取代(。):obj.send(:my_method, 3) #=>6send()方法的第一个参数是你要发送给对象的消息,也就是方法的名字。这里既可以使用字符串,也可以使用符号。但是一般认为符号会更好一些。所有剩下的参数(以及代码块)会直接传递给调用的... 阅读全文
posted @ 2013-04-30 20:38 巴晓鹏 阅读(386) 评论(0) 推荐(1) 编辑
 
摘要: 当一个类include多个模块,而这些模块中又有同名的方法时,类中调用的会是哪个模块的方法呢?先看下面的代码:module Printable def print #... end def prepare_cover #... endendmodule Document def print_to_screen prepare_cover format_for_screen ... 阅读全文
posted @ 2013-04-30 09:58 巴晓鹏 阅读(763) 评论(0) 推荐(1) 编辑

2013年4月29日

摘要: class MyClass;endobj1=MyClass.newobj2=MyClass.new对象由一组实例变量和一个类的引用组成。对象的方法存在于对象所属的类中(从类的角度看,它们叫做实例方法)。类本身是Class类的对象。类的名字不过就是一个常量而已。Class类是Module类的子类。一个模块基本上是由一组方法组成的包。类除了具有模块的特性之外,还可以被实例化(通过new()方法),以及被组织为层次结构(通过它的superclass()方法)。常量像文件系统一样,是按照树形结构组织的,其中模块和类的名字扮演目录的角色,其他普通的常量则扮演文件的角色。每个类都有一个祖先链,这个类从自己 阅读全文
posted @ 2013-04-29 12:11 巴晓鹏 阅读(359) 评论(0) 推荐(1) 编辑
 
摘要: 全局变量可以在任何作用域中访问:def a_scope $var = "some value"enddef another_scope $varenda_scopeanother_scope # => "some value"全局变量的问题在于系统的任何部分都可以修改它们,因此,我们几乎无法追踪谁把它们改成了什么。所以,如非必要,尽可能少使用全局变量。有时我们可以用顶级实例变量来代替全局变量。它们是顶级对象main的实例变量:@var = "The top-level @var"def my_method @varendmy_m 阅读全文
posted @ 2013-04-29 06:48 巴晓鹏 阅读(262) 评论(0) 推荐(1) 编辑