Ruby如何實現動態方法呼叫?

2021-06-21 16:56:50 字數 3000 閱讀 4263

在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...