2010-01-31 17 views
5

Necesito hacer que algunos métodos de instancia sean privados después de registrar ese objeto en otro objeto.Hacer que los métodos de instancia sean privados en tiempo de ejecución

No quiero congelar el objeto porque debe seguir siendo editable, solo que con menos funcionalidad. Y no quiero descifrar los métodos ya que se usan internamente.

Lo que necesito es algo así como:

class MyClass 

    def my_method 
    puts "Hello" 
    end 

end 

a = MyClass.new 
b = MyClass.new 

a.my_method       #=> "Hello" 
a.private_instance_method(:my_method) 
a.my_method       #=> NoMethodError 
b.my_method       #=> "Hello" 

¿Alguna idea?

Respuesta

4

Lo que es público y lo privado es por clase. Pero cada objeto puede tener su propia clase:

class Foo 

    private 

    def private_except_to_bar 
    puts "foo" 
    end 

end 

class Bar 

    def initialize(foo) 
    @foo = foo.dup 
    class << @foo 
     public :private_except_to_bar 
    end 
    @foo.private_except_to_bar 
    end 

end 

foo = Foo.new 
Bar.new(foo) # => "foo" 

foo.private_except_to_bar 
# => private method `private_except_to_bar' called for #<Foo:0xb7b7e550> (NoMethodError) 

Pero yuck. Considere estas alternativas:

  • Simplemente haga que el método sea público.
  • Explore diseños alternativos.
+0

Responde a mi duda: "Lo que es público y lo que es privado es por clase". Supongo que tengo que explorar otras alternativas. –

8

Puede llamar al método private en el nombre del método en cualquier momento para hacerlo privado:

>> class A 
>> def m 
>> puts 'hello' 
>> end 
>> end 
=> nil 
>> a = A.new 
=> #<A:0x527e90> 
>> a.m 
hello 
=> nil 
>> class A 
>> private :m 
>> end 
=> A 
>> a.m 
NoMethodError: private method `m' called for #<A:0x527e90> 
    from (irb):227 
    from /usr/local/bin/irb19:12:in `<main>' 

o, desde fuera de la clase:

A.send :private, :m 
+0

Eso hará que el método sea privado para todos los objetos de esa clase y no solo uno. –

5
class A 
    def test 
    puts "test" 
    end 
    def test2 
    test 
    end 
end 

a = A.new 

class << a 
    private :test 
end 

a.test2 # works 
a.test # error: private method 
Cuestiones relacionadas