プライバシーを尊重しながらメソッドを動的に呼び出す方法
-
05-07-2019 - |
質問
動的メソッド呼び出しの使用 (#send
または #method
) メソッドの可視性は無視されます。
プライベートメソッドの呼び出しに失敗するメソッドを動的に呼び出す簡単な方法はありますか?
解決
ご存じのとおり、public_sendメソッドが必要です:
----------------------------------------------------- Object#public_send obj.public_send(symbol [, args...]) => obj From Ruby 1.9.1 ------------------------------------------------------------------------ Invokes the method identified by _symbol_, passing it any arguments specified. Unlike send, public_send calls public methods only. 1.public_send(:puts, "hello") # causes NoMethodError
他のヒント
my_object.public_send :method, *args
Ruby 1.9の新機能です。古いRubyの場合、 require 'backports / 1.9.1 / kernel / public_send '
。
Ruby-1.9 を使用している場合は、次を使用できます Object#public_send
それはあなたが望むことをします。
Ruby-1.8.7 以前を使用している場合は、独自のコードを作成する必要があります。 Object#public_send
class Object
def public_send(name, *args)
unless public_methods.include?(name.to_s)
raise NoMethodError.new("undefined method `#{name}' for \"#{self.inspect}\":#{self.class}")
end
send(name, *args)
end
end
または、自分で書くこともできます Object#public_method
次のように動作します Object#method
ただしパブリックメソッドのみ
class Object
def public_method(name)
unless public_methods.include?(name.to_s)
raise NameError.new("undefined method `#{name}' for class `#{self.class}'")
end
method(name)
end
end
なぜそうするのか理解できないと思いますが、 eval
を使用できます。
class Klass
private
def private_method(arg)
end
end
k = Klass.new
m = "private_method"
eval "k.#{m}('an arg')"
NoMethodError: private method `private_method' called for #<Klass:0x128a7c0>
from (irb):15
from (irb):15
本当ですが、evalは実際に1.9より前に実際に行う唯一の方法だと思います。可視性について詳しく知りたい場合は、Jamis Buckが素晴らしい記事を書きました Rubyでメソッドの可視性が実際に意味するものについて。
Rubyの可視性は、他の言語と非常にわずかに異なります。
所属していません StackOverflow