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" ...
随机推荐
- 多线程编程(三)--创建线程之Thread VS Runnable
前面写过一篇基础的创建多线程的博文: 那么本篇博文主要来对照一下这两种创建线程的差别. 继承Thread类: 还拿上篇博客的样例来说: 四个线程各自卖各自的票,说明四个线程之间没有共享,是独立的线程. ...
- 说说JSON和JSONP 也许你会豁然开朗
说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决 前言 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只 ...
- UIViewController三种不同的初始化view的方式
You can specify the views for a view controller using a Storyboard created in Interface Builder. A s ...
- React Native开发技术
http://www.lcode.org/react-native-week-issue22/
- python入门(八):连接mysql和STMP
Python3 MySQL 数据库连接,使用 PyMySQL 连接数据库,并实现简单的增删改查. mysql连接步骤 1.打开数据库连接 2.使用cursor()方法获取操作游标 3.执行sql和异 ...
- CSS 属性的默认值
最近在看到一篇关于如何实现水平垂直居中,发现有许多属性值,自己并不了解,特此Google一番,查到,摘抄过来,方便以后查阅,下面是如何实现水平垂直居中的博文. 解读CSS布局之-水平垂直居中 html ...
- WPF 纯代码生成界面(不使用XAML)
对于编写 WPF 应用程序,只是用代码进行开发而不使用任何 XAML 不是常见的方式(但是仍然完全支持).只使用代码进行开发的明显缺点是,有可能会使用编写 WPF 应用程序成为极端乏味的工作. WPF ...
- SensorManager
光照传感器 Android 中每个传感器的用法其实都比较类似,真的可以说是一通百通了.首先第一步要获取到 SensorManager 的实例 SensorManager senserManager = ...
- Android之布局属性归纳
第一类:属性值为true或falseandroid:layout_centerHrizontal 水平居中android:layout_centerVertical 垂直居中android:layou ...
- ios开发-获取手机相关信息
今天在做客户端的时候,里面有个意见反馈功能. 调用系统带的邮件功能,发送邮件到指定邮箱. 然后我就想,应该在邮件正文部分添加手机相关内容,比如型号,版本,应用程序的版本等等,这样不仅使用者方便,开发者 ...