问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何运行一个ruby类 中的方法

发布网友 发布时间:2022-04-14 17:25

我来回答

1个回答

热心网友 时间:2022-04-14 18:54

在Ruby中,有多种方法可以实现方法的动态调用。
1.
使用send方法
第一种实现动态方法调用是使用send方法,send方法在Object类中定义,方法的第一个参数是一个符号用来表示所要调用的方法,后面则是所调用方法需要的参数。
“This
is
a
dog1″.send(:length)
=>
14
上面的代码中通过send方法去对一个字符串执行length操作,返回字符串的长度。
class
TestClass
def
hello(*args)
”Hello

+
args.join(‘
‘)
end
end
a
=
TestClass.new
puts
a.send
:hello,
“This”,
“is”,
“a”,
“dog!”
执行结果为:
Hello
This
is
a
dog!
2.
使用Method类和UnboundMethod类
另一种实现动态方法调用是使用Object类的method方法,这个方法返回一个Method类的对象。我们可以使用call方法来执行方法调用。
test1
=
“This
is
a
dog1″.method(:length)
test1.call
=>
14
class
Test
def
initialize(var)
@var
=
var
end
def
hello()
”Hello,
@var
=
#{@var}”
end
end
k
=
Test.new(10)
m
=
k.method(:hello)
m.call
#=>
“Hello,
@iv
=
99″
l
=
Test.new(‘Grant’)
m
=
l.method(“hello”)
m.call
#=>
“Hello,
@iv
=
Fred”
可以在使用对象的任何地方使用method对象,当调用call方法时,参数所指明的方法会被执行,这种行为有些像C语言中的函数指针。你也可以把method对象作为一个迭代器使用。
def
square(a)
a*a
end
mObj
=
method(:square)
[1,
2,
3,
4].collect(&mObj)
=>
[1
4
9
16]
Method对象都是和某一特定对象绑定的,也就是说你需要通过某一对象使用Method对象。你也可以通过UnboundMethod类创建对象,然后再把它绑定到某个具体的对象中。如果UnboundMethod对象调用时尚未绑定,则会引发异常。
class
Double
def
get_value
2
*
@side
end
def
initialize(side)
@side
=
side
end
end
a
=
Double.instance_method(:get_value)
#返回一个UnboundMethod对象
s
=
Double.new(50)
b
=
a.bind(s)
puts
b.call
执行结果为:
100
看下面一个更具体的例子:
class
CommandInterpreter
def
do_2()
print
“This
is
2
”;
end
def
do_1()
print
“This
is
1
”;
end
def
do_4()
print
“This
is
4
”;
end
def
do_3()
print
“This
is
3
”;
end
Dispatcher
=
{
?2
=>
instance_method(:do_2),
?1
=>
instance_method(:do_1),
?4
=>
instance_method(:do_4),
?3
=>
instance_method(:do_3)
}
def
interpret(string)
string.each_byte
{|i|
Dispatcher[i].bind(self).call
}
end
end
interpreter
=
CommandInterpreter.new
interpreter.interpret(’1234′)
执行结果为:
This
is
1
This
is
2
This
is
3
This
is
4
3.
使用eval方法
我们还可以使用eval方法实现方法动态调用。eval方法在Kernel模块中定义,有多种变体如class_eval,mole_eval,instance_eval等。Eval方法将分析其后的字符串参数并把这个字符串参数作为Ruby代码执行。
str
=
“Hello”
eval
“str
+

World!’”
=>
Hello
World!
sentence
=
%q{“This
is
a
test!”.length}
eval
sentence
=>
15
当我们在使用eval方法时,我们可以通过eval方法的第二个参数指明eval所运行代码的上下文环境,这个参数可以是Binding类对象或Proc类对象。Binding类封装了代码在某一环境运行的上下文,可以供以后使用。
class
BindingTest
def
initialize(n)
@value
=
n
end
def
getBinding
return
binding()
#使用Kernel#binding方法返回一个Binding对象
end
end
obj1
=
BindingTest.new(10)
binding1
=
obj1.getBinding
obj2
=
BindingTest.new(“Binding
Test”)
binding2
=
obj2.getBinding
puts
eval(“@value”,
binding1)
#=>
10
puts
eval(“@value”,
binding2)
#=>
Binding
Test
puts
eval(“@value”)
#=>
nil
可以看到上述代码中,@value在binding1所指明的上下文环境中值为10,在binding2所指明的上下文环境中值为Binding
Test。当eval方法不提供binding参数时,在当前上下文环境中@value并未定义,值为nil。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
巴西龟最长活多久,家养!!! 养胃的药最好的是什么啊 婴儿积食发烧不愿吃药怎么办 板门穴位在哪个部位 手机设置放偷看的方法? 凝结水回收器生产厂家? 个人账户养老金预测公式:现有5万元,缴费20年,能领多少钱? 临沂比较有名的男装品牌 呼伦贝尔市悦动网络科技有限公司怎么样? 呼伦贝尔中汇实业有限公司怎么样? 背景图怎么设置 急需电大财务报表分析网上形成性考核作业答案 5家上市公司(歌华有线、江铃汽车、青岛海尔、万科A)选择一 2015年万科流动资产总额是多少 母公司控股50%以下,但是是实际控制人,母公司的这项长期股权投资是成本法还是权益法核算? 看中了一只NIKE的LED运动手表。在哪买啊?????急急急...... 战斗机LED时尚运动手表怎样调日期 路由器恢复出厂设置后怎么设置图解 配备业界领先的反射屏 华米Amazfit智能运动手表3评测 阿迪达斯led运动手表手表左下键有什么用? 运动手表为什么不应LED屏 oppo手机屏锁图案密码忘了怎么办 提拉米苏的来由,资料什么的?有什么寓意吗? 谁知道关于提拉米苏的传说 意大利提拉米苏的起源 在PROE里怎麼算产品的重量?2001版 提拉米苏的起源?具体做法? 提拉米苏名字的由来 提拉米苏慕斯的历史是什么? 请问在PROE里面怎样来称产品的重量呢? 提拉米苏来自哪个国家 股票万科和招商银行哪支做为长期投资好?谢谢 1股票万科和招商银行,中国铝业哪支做为长期投资好?谢谢 求防务新观察 股票万科和招商银行,中国铝业哪支做为长期投资好?谢谢 哪里能看到防务新观察的全部视频记得以前可以在cctv 上看到的 关于会计学的问题 《防务新观察》百慕大:美国核潜艇神秘失踪的视频 换了以前的微信好友怎么找回来? 万科保卫战给中国企业 带来什么启示 央视7套的防务新观察几点播出 防务新观察的视频怎么下载 那里有防务新观察20090711视频播放地址的? 在那里看防务新观察20090712在线观看视频,防务新观察20090712下载,防务新观察20090712观看 手机上哪里可以看看防务新观察 有谁知道报道追近发生的国内外军事新闻的视频,每周出一期的。如《军情观察室》就很好,还有没其它这样... 病人中秋节晚上梦见去世多年的爸爸姑姑,下了好多雪是什么? 防务新观察怎么改版了 换了以前的微信好友怎么找回来? 请问:军事专家张召忠是在哪一期《防务新观察》上说:土耳其不敢击落俄罗斯战机的,谢谢 货拉拉跨市接单需要人脸识别吗?