在ruby中,有多種方法可以實現方法的動態呼叫。
1. 使用send方法
第一種實現動態方法呼叫是使用send方法,send方法在object類中定義,方法的第乙個引數是乙個符號用來表示所要呼叫的方法,後面則是所呼叫方法需要的引數。
「this is a dog1″.send(:length) => 14
上面的**中通過send方法去對乙個字串執行length操作,返回字串的長度。
class testclass
def hello(*args)
」hello 」 + args.join(『 『)
endend
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
enddef hello()
」hello, @var = #」
endend
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*aend
mobj = method(:square)
[1, 2, 3, 4].collect(&mobj) => [1 4 9 16]
method物件都是和某一特定物件繫結的,也就是說你需要通過某一物件使用method物件。你也可以通過unboundmethod類建立物件,然後再把它繫結到某個具體的物件中。如果unboundmethod物件呼叫時尚未繫結,則會引發異常。
class double
def get_value
2 * @side
enddef initialize(side)
@side = side
endend
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\n」; end
def do_1() print 「this is 1\n」; end
def do_4() print 「this is 4\n」; end
def do_3() print 「this is 3\n」; end
dispatcher =
def interpret(string)
string.each_byte
endend
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,module_eval,instance_eval等。eval方法將分析其後的字串引數並把這個字串引數作為ruby**執行。
str = 「hello」
eval 「str + 『 world!』」 => hello world!
sentence = %q
eval sentence => 15
當我們在使用eval方法時,我們可以通過eval方法的第二個引數指明eval所執行**的上下文環境,這個引數可以是binding類物件或proc類物件。binding類封裝了**在某一環境執行的上下文,可以供以後使用。
class bindingtest
def initialize(n)
@value = n
enddef getbinding
return binding() #使用kernel#binding方法返回乙個binding物件
endend
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。
**:
動態呼叫方法
若 action 中存在多個方法,但在配置檔案中註冊該 action 時,並未為每個方法指定乙個,而是只為這一 個 action 類註冊了乙個。那麼,當使用者訪問該的時,到底執行哪個方法,則是由使用者發出的請求動 態決定。即僅從配置檔案是看不出 標籤是對應哪個方法的,只有在執行時根據具體的使用者請求...
動態方法呼叫
jsp檔案 1 actionmethod dmi 動態方法呼叫 action執行的時候並不一定要執行execute方法,1 可以在配置檔案中配置action的時候用method 來指定執行哪個方法 user useradd 新增使用者 2 也可以在url位址中動態指定 動態方法呼叫dmi 推薦 us...
動態方法呼叫
如果action中存在多個方法時,我們可以使用 方法名呼叫指定方法。如下 public class helloworldaction public string other throws exception 假設訪問上面action的url路徑為 struts test helloworld.act...