ruby中的可调用对象--方法
上一篇讲了ruby中的可调用对象proc和lambda,他们都是块转换成的对象。ruby中的可调用对象还有方法。通过使用method方法,并且以方法名作为参数(字符串或者符号),就可以得到一个方法对象。
如下:
class C
def talk
p "hello world"
end
end c = C.new
meth = c.method :talk
meth.call
输出: "hello world"
类C有个实例方法talk。类C的实例c调用方法method,并且用:talk做参数,得到一个方法对象meth。然后meth调用call,输出"hello world"。
值得注意的是,meth这个方法对象是绑定在对象c上的方法。调用call的时候,也知道是c在调用talk方法。
可以用Method#unbind()方法来把一个方法跟它绑定的对象相分离,该方法返回一个UnboundMethod对象,不能执行UnboundMethod对象,必须把它绑定到一个对象上,使之再次成为一个Method对象。
如下:(在上面代码的基础上)
class D < C
end
d = D.new
unbound = meth.unbind
new_meth = unbound.bind(d)
new_meth.call
输出: "hello world"
unbind解绑之后,绑定到C的子类D的一个实例对象d上。再对方法对象调用call。如果不想对一个已绑定的方法进行解绑,可以用如下的代码得到解绑对象:
unbound = C.instance_method (:talk)
为什么要这样呢?存在总是合理的,绑定与解绑也有它的适用之处。
在之前《ruby中的方法查找》中,我们知道ruby的方法调用是根据匹配到的第一个方法来调用的。那么如果要调用匹配路径上的匹配到的第二个方法呢?ruby中有super这个关键字。但是加入super关键字相当于改变了这个方法。它并不是直接调用了匹配路径上的第二个方法。而是在匹配到的第一个方法里调用第二个方法。还有,如果要调用匹配路径上的第三个匹配到的方法呢?第四个呢?这个就可以用到绑定的方法了。
如下:
class C
def method
p "this is in C"
end
end class D < C
def method
p "this is in D"
end
end class E < D
def method
p "this is in E"
end
end e = E.new
e.method D.instance_method(:method).bind(e).call
C.instance_method(:method).bind(e).call
输出:
"this is in E"
"this is in D"
"this is in C"
如代码所示,定义类C,D,E,D继承C,E继承D。他们都定义了方法method。那么E的实例e的方法查找路径上这三个method都可以调用。如果直接调用e.method。那么肯定是调用了第一个匹配的方法,也就是类E中的方法,如输出的第一行。如果要调用类D中的方法method呢?如代码22行。把D的实例方法绑定到对象e上,然后在调用。调用类C中的方法method,同理。如23行。
学过C++的话,看到这个可能会想到派生类指针引用基类对象。派生类是基类的特例,所以只有强制转换类型之后才能引用基类的对象。和ruby中的绑定类似,只有和父类的方法绑定以后,才能调用父类的方法。
和上一篇一起做一个总结。ruby中可以被调用的对象有:
块(不算是对象,可以被调用),proc(Proc类的对象),lambda(Proc类的对象),这三种都是在定义它们的作用域中执行。
方法:绑定于对象,在所绑定的对象的作用域中执行。
将一种对象转换成另一种对象的方法有:Proc.new(),Method#to_proc(),&操作符
ruby中的可调用对象--方法的更多相关文章
- ruby中的可调用对象--proc和lamdba
ruby中将块转变成对象的三种方法 ruby中的大部分东西都是对象,但是块不是.那么,如果你想存下来一个块,方便以后使用,你就需要一个对象.ruby中有三种方法,把块转换成可以利用的对象. Proc. ...
- Oracle自定义数据类型 2 (调用对象方法)
调用对象方法 调用对象方法基于类型创建表后,就可以在查询中调用对象方法 A. 创建基于对象的表语法: create table <表名> of <对象类型>意义 ...
- Ruby中区分运行来源的方法(转)
Ruby中区分运行来源的方法 这篇文章主要介绍了Ruby中区分运行来源的方法,本文讲解的是类似Python中的if name == 'main':效果,其实Ruby中也有类似语法,需要的朋友可以参考下 ...
- Java 调用对象方法的执行过程
弄清调用对象方法的执行过程十分重要.下面是调用过程的详细描述: 1) 编译器查看对象的声明类型和方法名.假设调用x.f(param),且隐式参数x声明为C类的对象.需要注意的是:有可能存在多个名为f, ...
- java 中使用ajax调用后台方法注意事项
java 中使用ajax调用后台方法注意事项,后台方法一定要加@ResponseBody jQuery.validator.addMethod("checkRuleName",fu ...
- ongl表达式中得到对象,调用对象方法(OA项目权限显示模块)
在用户是否拥有某项权限的问题 是这样解决的: 用户登录之后 登录信息是保存在session域中的 通过el表达式可得到登录的对象信息 那么怎样判断用户是否拥有某项权限呢 ?如果没有上图中的判断 ...
- OC基础--OC中的类方法和对象方法
PS:个人感觉跟C#的静态方法和非静态方法有点类似,仅仅是有点类似.明杰老师说过不要总跟之前学过的语言做比较,但是个人觉得,比较一下可以加深印象吧.重点是自己真的能够区分开! 一.OC中的对象方法 1 ...
- 【Python】Python中子类怎样调用父类方法
python中类的初始化方法是__init__(),因此父类子类的初始化方法都是这个,如果子类不实现这个函数,初始化时调用父类的初始化函数,如果子类实现这个函数,就覆盖了父类的这个函数,既然继承父类, ...
- String在方法中的传递方式(调用外部方法给String变量赋值时,未得到预期结果)
示例: public class StringTraining { public static void changeStr(String str){ str = "137878" ...
随机推荐
- xsocket:空闲超时问题。
XSocket是什么? java的nio的封装. 详情: 1. http://xsocket.sourceforge.net/core/apidocs/2_1/index.html 2. http:/ ...
- hdu 2025:查找最大元素(水题,顺序查找)
查找最大元素 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- [转]这五种方法前四种方法只支持IE浏览器,最后一个方法支持当前主流的浏览器(火狐,IE,Chrome,Opera,Safari)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Popwindow系列
一系列干货等你来拿 关于我:http://www.cnblogs.com/dubo-/ 项目中也有很多实用的事例,等待录入中...
- 《C++ Primer Plus》第8章 函数探幽 学习笔记
C++ 扩展了 C 语言的函数功能.通过将 inline 关键字用于函数定义,并在首次调用该函数前提供其函数定义,可以使得 C++ 编译器将该函数视为内联函数.也就是说,编译器不是让程序跳到独立的代码 ...
- Objective-C内存管理基础
2011-05-11 15:45 朱祁林 http://zhuqil.cnblogs.com 字号:T | T 本文我们将介绍<Objective-C内存管理基础>,在iOS开发中,内存管 ...
- centos7 安装kafka Manager
1.安装sbt编译环境 curl https://bintray.com/sbt/rpm/rpm |tee /etc/yum.repos.d/bintray-sbt-rpm.repo yum inst ...
- 170324、Spring 处理器和Resource
1.Spring 框架允许开发者使用两种后处理器扩展 IoC 容器,这两种后处理器扩展 IoC 容器,这两种后处理器可以后处理 IoC 容器本身,或对容器中所有的 Bean 进行后处理.IoC 容器还 ...
- 160316、实时处理oracle数据库中表的数据变化
http://blog.csdn.net/as339000204/article/details/45390727 近期接受项目需求,需要实时处理oracle数据库中表的数据变化,首先想到的是 ...
- 原生封装的ajax
原生封装的ajax的代码如下: //将数据转换成 a=1&b=2格式; function json2url(json){ var arr = []; //加随机数防止缓存; json.t = ...