動(dòng)態(tài)定義方法
本章節(jié)我會(huì)為大家講一下 Ruby 元編程中如何動(dòng)態(tài)定義方法。
1. 如何動(dòng)態(tài)定義一個(gè)方法
我們會(huì)使用define_method
來動(dòng)態(tài)定義方法。
實(shí)例:
class Account
attr_accessor :state
(1..99).each do |i|
define_method("credit_#{i}".to_sym) do
self.state = state + i
end
define_method("debit_#{i}".to_sym) do
self.state = state - i
end
end
def initialize(state)
@state = state
end
end
account = Account.new(20)
account.credit_31
account.state # => 51
account.debit_45
account.state # => 6
方法會(huì)被顯示到 public_methods
列表中。
account.public_methods(false)
# [ ... , :credit_83, :debit_83, :credit_84, :debit_84, ...]
account.respond_to?(:debit_19)
# => true
method = account.public_method(:debit_19)
# => #<Method: Account#debit_19>
2. 動(dòng)態(tài)定義方法時(shí)傳遞參數(shù)
2.1 強(qiáng)制參數(shù)
實(shí)例:
class Bar
define_method(:foo) do |arg1, arg2|
arg1 + arg2
end
end
a = Bar.new
a.foo
#=> ArgumentError (wrong number of arguments (given 0, expected 2))
a.foo 1, 2
# => 3
2.2 可選參數(shù)
class Bar
define_method(:foo) do |arg=nil|
arg
end
end
a = Bar.new
a.foo
#=> nil
a.foo 1
# => 1
2.3 任意數(shù)量參數(shù)
實(shí)例:
class Bar
define_method(:foo) do |arg=nil|
arg
end
end
a = Bar.new
a.foo
#=> nil
a.foo 1
# => 1
2.4 固定鍵值對(duì)的哈希參數(shù)
實(shí)例:
class Bar
define_method(:foo) do |option1: 'default value', option2: nil|
"#{option1} #{option2}"
end
end
bar = Bar.new
bar.foo option2: 'hi'
# => "default value hi"
bar.foo option2: 'hi',option1: 'ahoj'
# => "ahoj hi"
2.5 任意鍵值對(duì)數(shù)量的哈希參數(shù)
實(shí)例:
class Bar
define_method(:foo) do |**keyword_args|
keyword_args
end
end
bar = Bar.new
bar.foo option1: 'hi', option2: 'ahoj', option3: 'ola'
# => {:option1=>"hi", :option2=>"ahoj", :option3=>"ola"}
2.6 傳遞block
實(shí)例:
class Bar
define_method(:foo) do |&block|
p block.call
end
end
bar = Bar.new
bar.foo do
'six'
end
# => "six"
2.7 所有參數(shù)
實(shí)例:
class Bar
define_method(:foo) do |variable1, variable2, *arg, **keyword_args, &block|
p variable1
p variable2
p arg
p keyword_args
p block.call
end
end
bar = Bar.new
bar.foo :one, 'two', :three, 4, 5, foo: 'bar', car: 'dar' do
'six'
end
## will print:
:one
"two"
[:three, 4, 5]
{ foo: "bar", car: "dar" }
'six'
注意事項(xiàng):傳遞所有參數(shù)需要按照普通參數(shù)、不指定數(shù)目的參數(shù)、哈希參數(shù)、block的順序來設(shè)置。
3. 小結(jié)
本章節(jié)中我們學(xué)習(xí)了使用define_method
來動(dòng)態(tài)定義方法,如何傳遞參數(shù),以及傳遞參數(shù)的順序應(yīng)該按照arg、*args、**keyword_args、block
的順序來設(shè)置。