una programas programacion poo objetos llamar herencia ejemplos con codigo clases clase ruby messaging introspection dynamic-languages

programas - programacion con objetos ruby



¿Alguna forma de determinar qué objeto llama un método? (5)

¿Quieres decir como self ?

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

Espero que la infraestructura de transmisión de mensajes de Ruby signifique que podría haber algún truco inteligente para esto.

¿Cómo puedo determinar el objeto que llama? ¿Qué objeto se llama el método en el que estoy actualmente?


La answer de Pedro utilizada en el ejemplo de código de producción.

En mi compañía, estábamos desaprobando la bandera deleted en el sabor de la columna deleted de Paranoia gema . El siguiente código es cómo nos aseguramos de que todo saldrá bien antes de eliminar la columna (implementando este código y luego de 2 o 3 días de estar remoove_column :lessons, :deleted implementamos la migración 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


Puede mirar fácilmente la línea de código que llamó la función de interés a través de

caller.first

que le indicará el nombre del archivo y el número de línea que llamó a la función relevante. A continuación, podría volver a calcular qué objeto era.

Sin embargo, parece que estás más cerca de un objeto que llama una función determinada, tal vez dentro de un método de instancia. No tengo conocimiento de un método para resolver esto, pero no lo usaría de todos modos, ya que parece violar gravemente la encapsulación.


Tecnología en su máxima expresión:

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>''"]

Nota: Número de línea para fines demostrativos. phone.rb:X refiere a la línea X del script.

Mira phone.rb:13 ! Este método de dial es lo que envió la llamada! ¡Y phone.rb:22 refiere al controlador imprudente que utilizó el método de dial !


Como opción, hay una gema binding_of_caller que le permite ejecutar código en el contexto de cualquier persona que llama en la pila de llamadas (persona que llama, persona que llama, etc.). Es útil para inspeccionar (leer hacer cualquier cosa en cualquier posición en la pila de llamadas) pila de llamadas en desarrollo, tal como se utiliza en better_errors .

Los objetos de Class Binding encapsulan el contexto de ejecución en algún lugar particular del código y retienen este contexto para uso futuro.

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

Debo mencionar que esta técnica solo debe usarse para fines de depuración, diversión o educación , ya que viola los principios de la POO realmente mal.
Sobre todo debido a eval .

Vamos a preparar cosas:

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

Obtenga la instancia de llamante inmediata (más cercana en la pila, por lo tanto, 0 ):

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

... o incluso un método de llamada inmediata:

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

Si necesita subir más arriba en la pila de llamadas, use números distintos a 0 para obtener el enlace de una persona que llama.

Terriblemente hacky Pero si realmente necesitas esto, ahí tienes.