objetos metodos manejo lista importar herencia clases clase ruby scope visibility class-method access-specifier

metodos - manejo de objetos en ruby



¿Hay alguna manera de llamar a un método de Clase privado desde una instancia en Ruby? (6)

A menos que sea un malentendido, ¿no necesitas algo como esto?

class Foo private def Foo.bar # Complex logic goes here puts "hi" end public def bar Foo.bar end end

Por supuesto, podría cambiar la segunda definición para usar su enfoque self.class.send si desea evitar la codificación física del nombre de la clase ...

Aparte de self.class.send :method, args... , por supuesto. Me gustaría poner a disposición un método bastante complejo tanto a nivel de clase como de instancia sin duplicar el código.

ACTUALIZAR:

@ Jonathan Branam: esa era mi suposición, pero quería asegurarme de que nadie más hubiera encontrado una forma de evitarlo. La visibilidad en Ruby es muy diferente de la de Java. También tienes razón en que el private no funciona en los métodos de clase, aunque esto declarará un método de clase privado:

class Foo class <<self private def bar puts ''bar'' end end end Foo.bar # => NoMethodError: private method ''bar'' called for Foo:Class


Aquí hay un fragmento de código para acompañar la pregunta. El uso de "privado" en una definición de clase no se aplica a los métodos de clase. Necesita usar "private_class_method" como en el siguiente ejemplo.

class Foo def self.private_bar # Complex logic goes here puts "hi" end private_class_method :private_bar class <<self private def another_private_bar puts "bar" end end public def instance_bar self.class.private_bar end def instance_bar2 self.class.another_private_bar end end f=Foo.new f=instance_bar # NoMethodError: private method `private_bar'' called for Foo:Class f=instance_bar2 # NoMethodError: private method `another_private_bar'' called for Foo:Class

No veo una manera de evitar esto. La documentación dice que no puede especificar la recepción de un método privado. Además, solo puedes acceder a un método privado desde la misma instancia. La clase Foo es un objeto diferente de una instancia determinada de Foo.

No tomes mi respuesta como definitiva. Definitivamente no soy un experto, pero quería proporcionar un fragmento de código para que otros que intenten responder tengan métodos de clase propiamente privados.


Esta es la forma de jugar con métodos de clase privada "reales".

class Foo def self.private_bar # Complex logic goes here puts "hi" end private_class_method :private_bar class <<self private def another_private_bar puts "bar" end end public def instance_bar self.class.private_bar end def instance_bar2 self.class.another_private_bar end def calling_private_method Foo.send :another_private_bar self.class.send :private_bar end end f=Foo.new f.send :calling_private_method # "bar" # "hi" Foo.send :another_private_bar # "bar"

aclamaciones


Hoy en día ya no necesitas los métodos de ayuda. Simplemente puede alinearlos con la definición de su método. Esto debería ser muy familiar para la gente de Java:

class MyClass private_class_method def self.my_private_method puts "private class method" end private def my_private_method puts "private instance method" end end

Y no, no puedes llamar a un método de clase privado desde un método de instancia. Sin embargo, en su lugar, podría implementar el método de clase privada como método de clase pública en una clase anidada privada , utilizando el método de ayuda private_constant . Vea este blogpost para más detalles.


Permítanme contribuir a esta lista de soluciones más o menos extrañas y no soluciones:

puts RUBY_VERSION # => 2.1.2 class C class << self private def foo ''Je suis foo'' end end private define_method :foo, &method(:foo) def bar foo end end puts C.new.bar # => Je suis foo puts C.new.foo # => NoMethodError


Si su método no es más que una función de utilidad (es decir, no depende de variables de instancia), puede poner el método en un módulo e include y extend la clase para que esté disponible tanto como un método de clase privada como privado método de instancia.