14

私が「送信」方法を理解している限り、これは

some_object.some_method("im an argument")

これと同じです

some_object.send :some_method, "im an argument"

では、「send」メソッドを使用するポイントは何ですか?

4

5 に答える 5

20

メソッドの名前が事前にわからない場合に便利です。たとえば、メタプログラミングを行う場合は、変数にメソッドの名前を入れて、それをsendメソッドに渡すことができます。

プライベートメソッドを呼び出すためにも使用できますが、この特定の使用法は、ほとんどのRuby開発者にとって良い習慣とは見なされていません。

class Test
  private
  def my_private_method
    puts "Yay"
  end
end

t = Test.new

t.my_private_method # Error

t.send :my_private_method #Ok

public_sendただし、パブリックメソッドのみを呼び出すことができるようにするために使用できます。

于 2013-02-10T00:00:51.283 に答える
6

In addition to Intrepidd's use cases, it is convenient when you want to route different methods on the same receiver and/or arguments. If you have some_object, and want to do different things on it depending on what foo is, then without send, you need to write like:

case foo
when blah_blah then some_object.do_this(*some_arguments)
when whatever then some_object.do_that(*some_arguments)
...
end

but if you have send, you can write

next_method =
case foo
when blah_blah then :do_this
when whatever then :do_that
....
end
some_object.send(next_method, *some_arguments)

or

some_object.send(
  case foo
  when blah_blah then :do_this
  when whatever then :do_that
  ....
  end,
  *some_arguments
)

or by using a hash, even this:

NextMethod = {blah_blah: :do_this, whatever: :do_that, ...}
some_object.send(NextMethod[:foo], *some_arguments)
于 2013-02-10T04:08:00.483 に答える
4

他のすべての人の答えに加えて、増分桁を含むメソッドを反復処理するのが良いユースケースです。

class Something
  def attribute_0
    "foo"
  end
  def attribute_1
    "bar"
  end
  def attribute_2
    "baz"
  end
end

thing = Something.new

3.times do |x|
  puts thing.send("attribute_#{x}")
end

#=> foo
# bar
# baz

これは些細なことのように思えるかもしれませんが、RailsのコードとテンプレートをDRYに保つのに役立つことがあります。これは非常に特殊なケースですが、有効なケースだと思います。

于 2014-07-11T00:56:22.200 に答える
0

同僚がすでに言ったことを簡単に要約するとsend、メソッドはメタプログラミングのシンタックスシュガーです。以下の例は、メソッドへのネイティブ呼び出しが不可能である可能性が高い場合を示しています。

class Validator
  def name
    'Mozart'
  end
  def location
    'Salzburg'
  end
end

v = Validator.new
'%name% was born in %location%'.gsub (/%(?<mthd>\w+)%/) do
  # v.send :"#{Regexp.last_match[:mthd]}"
  v.send Regexp.last_match[:mthd].to_sym
end
=> "Mozart was born in Salzburg" 
于 2013-02-10T04:51:27.217 に答える
-1

私はこの共演が好きです

Object.get_const("Foo").send(:bar)
于 2013-02-10T07:42:08.710 に答える