Подтвердить что ты не робот

Любой способ определить, какой объект называется методом?

Я надеюсь, что инфраструктура передачи сообщений Ruby означает, что для этого может быть какой-то умный трюк.

Как определить вызывающий объект - какой объект называется методом, в котором я сейчас?

4b9b3361

Ответ 1

В качестве опции существует binding_of_caller gem, который позволяет выполнять код в контексте любого вызывающего абонента в стеке вызовов (вызывающий, вызывающий абонент и т.д.). Это полезно для того, чтобы в процессе разработки (см. "Сделать что-нибудь в любой позиции в стеке вызовов" ), как используется в better_errors.

Объекты класса Binding инкапсулируют контекст выполнения в определенном месте в коде и сохраняют этот контекст для будущего использования.

http://www.ruby-doc.org/core-2.1.4/Binding.html

Следует ли упомянуть, что этот метод должен использоваться только для отладки, развлечений или образовательных целей, потому что он сильно нарушает принципы ООП.
В основном из-за eval.

Пусть готовят материал:

require 'binding_of_caller' # I assume, you installed this gem already?

Получите

немедленный (ближайший к стеку, следовательно 0) экземпляр вызывающего:
binding.of_caller(0).eval('self')

... или даже метод немедленного вызова:

binding.of_caller(0).eval('__method__')

Если вам нужно подняться выше стека вызовов, используйте номера, отличные от 0 для получения привязки звонящего.

Ужасно хаки. Но если вам действительно нужно это? там вы идете.

Ответ 2

Вы можете легко просмотреть строку кода, которая вызвала интересующую функцию через

caller.first

который укажет вам имя файла и номер строки, который называется соответствующей функцией. Вы могли бы затем запрограммировать, какой именно объект.

Однако, похоже, вы больше после некоторого объекта, который вызывает определенную функцию, возможно, в методе экземпляра. Я не знаю метода для выяснения этого - но я бы не использовал его в любом случае, поскольку он, похоже, плохо нарушает инкапсуляцию.

Ответ 3

Технология в лучшем виде:

 1  # phone.rb
 2  class Phone
 3    def caller_id
 4      caller
 5    end
 6  end
 7  
 8  class RecklessDriver
 9    def initialize
10      @phone = Phone.new
11    end
12    def dial
13      @phone.caller_id
14    end
15  end
16  
17  p = Phone.new
18  p.caller_id.inspect   # => ["phone.rb:18:in `<main>'"]
19  
20  macek = RecklessDriver.new
22  macek.dial.inspect    # => ["phone.rb:13:in `dial'", "phone.rb:22:in `<main>'"]

Примечание: Номер строки для демонстрационных целей. phone.rb:X относится к строке X script.

Посмотрите phone.rb:13! Этот метод dial - это то, что послал вызов! И phone.rb:22 относится к безрассудному драйверу, который использовал метод dial!

Ответ 4

Вы имеете в виду как self?

irb> class Object
  ..   def test
  ..     self
  ..   end
  .. end
  => nil
irb> o = Object.new
  => #<Object:0xb76c5b6c>
irb> o.test
  => #<Object:0xb76c5b6c>

Ответ 5

Peter ответ, используемый в примере производственного кода

В моей компании мы осуждали флаг deleted в аромате Paranoia gem deleted_at. Ниже приведен код, как мы гарантируем, что все будет хорошо, прежде чем мы удалим столбец (развертывание этого кода, а затем через 2 или 3 дня жизни мы развертываем миграцию remoove_column :lessons, :deleted

class Lesson < ActiveRecord::Base

  def deleted
    if caller.select { |c| c.match /serialization\.rb/ }.any?
      # this is Rails object mapping
      !!deleted_at
    else
      raise 'deplicated - deleted was replaced by  deleted_at'
    end
  end
end