上一篇讲了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中的可调用对象--方法的更多相关文章

  1. ruby中的可调用对象--proc和lamdba

    ruby中将块转变成对象的三种方法 ruby中的大部分东西都是对象,但是块不是.那么,如果你想存下来一个块,方便以后使用,你就需要一个对象.ruby中有三种方法,把块转换成可以利用的对象. Proc. ...

  2. Oracle自定义数据类型 2 (调用对象方法)

    调用对象方法 调用对象方法基于类型创建表后,就可以在查询中调用对象方法 A. 创建基于对象的表语法: create   table   <表名>   of   <对象类型>意义 ...

  3. Ruby中区分运行来源的方法(转)

    Ruby中区分运行来源的方法 这篇文章主要介绍了Ruby中区分运行来源的方法,本文讲解的是类似Python中的if name == 'main':效果,其实Ruby中也有类似语法,需要的朋友可以参考下 ...

  4. Java 调用对象方法的执行过程

    弄清调用对象方法的执行过程十分重要.下面是调用过程的详细描述: 1) 编译器查看对象的声明类型和方法名.假设调用x.f(param),且隐式参数x声明为C类的对象.需要注意的是:有可能存在多个名为f, ...

  5. java 中使用ajax调用后台方法注意事项

    java 中使用ajax调用后台方法注意事项,后台方法一定要加@ResponseBody jQuery.validator.addMethod("checkRuleName",fu ...

  6. ongl表达式中得到对象,调用对象方法(OA项目权限显示模块)

    在用户是否拥有某项权限的问题  是这样解决的: 用户登录之后  登录信息是保存在session域中的  通过el表达式可得到登录的对象信息  那么怎样判断用户是否拥有某项权限呢 ?如果没有上图中的判断 ...

  7. OC基础--OC中的类方法和对象方法

    PS:个人感觉跟C#的静态方法和非静态方法有点类似,仅仅是有点类似.明杰老师说过不要总跟之前学过的语言做比较,但是个人觉得,比较一下可以加深印象吧.重点是自己真的能够区分开! 一.OC中的对象方法 1 ...

  8. 【Python】Python中子类怎样调用父类方法

    python中类的初始化方法是__init__(),因此父类子类的初始化方法都是这个,如果子类不实现这个函数,初始化时调用父类的初始化函数,如果子类实现这个函数,就覆盖了父类的这个函数,既然继承父类, ...

  9. String在方法中的传递方式(调用外部方法给String变量赋值时,未得到预期结果)

    示例: public class StringTraining { public static void changeStr(String str){ str = "137878" ...

随机推荐

  1. Linxu内核参数详解

    #表示SYN队列的长度,默认为1024,加大队列长度,可以容纳更多等待连接的网络连接数. net.ipv4.tcp_max_syn_backlog = 65536 #每个网络接口接收数据包的速率比内核 ...

  2. ChemDraw使用不了怎么办

    ChemDraw作为一款专业级的化学绘图软件,不仅可以帮助用户绘制图像在数据计算方面也起了很大作用,因此,ChemDraw非常受用户的欢迎.但是我们在使用过程中难免会遇到各种问题,特别是对于新手用户, ...

  3. 采用std::thread 替换 openmp

    内容转换的,具体详见博客:https://cloud.tencent.com/developer/article/1094617 及对应的code:https://github.com/cpuimag ...

  4. insmod 内核模块参数传递

    对于如何向模块传递参数,Linux kernel 提供了一个简单的框架.其允许驱动程序声明参数,并且用户在系统启动或模块装载时为参数指定相应值,在驱动程序里,参数的用法如同全局变量. 通过宏modul ...

  5. 部署全局ajax处理

    $.ajaxSetup({ beforeSend:function(){ $('.loading').show(); }, complete:function(){ $('.loading').fad ...

  6. 利用hugo生成静态站点

    动机 使用Markdown撰写博客,并以静态页面形式发布. 选择hugo 现在jekyll似乎更加流行,但是jekyll是基于Ruby的,在windows下安装很繁琐. 而hugo是用go写的,win ...

  7. Java Web项目BlogAutoGenerator编写日志1

    使用的数据库是MySQL,所以首先要在MySQL中创建database和表.建立数据库article_db,建立表blog,如下: create database article_db DEFAULT ...

  8. css位置相关元素

    1.border     是边框的意思,它可以设置粗细,多少像素,输入样式,solid是实线的意思,可以直接选择color边框的颜色. 也可以设置某个方向的边框,例如 设置一个div,让它的高和宽都为 ...

  9. poj_2823 单调队列

    题目大意 给定一行数,共N个.有一个长度为K的窗口从左向右滑动,窗口中始终有K个数字,窗口每次滑动一个数字.求各个时刻窗口中的最大值和最小值. 题目分析 直接搜索,复杂度为O(n^2).考虑使用单调队 ...

  10. html的table列表根据奇数还是偶数行显示不同颜色

    <tr <s:if test="#sts.even"> class="table_1" onMouseOut="this.class ...