2010-01-31 12 views
5

Ho bisogno di rendere privati ​​alcuni metodi di istanza dopo aver registrato quell'oggetto in un altro oggetto.Rendi privati ​​i metodi di istanza in runtime

Non voglio bloccare l'oggetto perché deve rimanere modificabile, solo con meno funzionalità. E non voglio disfare i metodi poiché sono usati internamente.

Che cosa ho bisogno è qualcosa di simile:

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" 

Tutte le idee?

risposta

4

Cosa c'è di pubblico e ciò che è privato è per classe. Ma ogni oggetto può avere una sua classe:

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) 

Ma schifo. Considera queste alternative:

  • Basta rendere pubblico il metodo.
  • Esplora progetti alternativi.
+0

Questo risponde al mio dubbio: "Ciò che è pubblico e ciò che è privato è per classe". Credo di dover esplorare altre alternative. –

8

È possibile chiamare il metodo private sul nome del metodo in qualsiasi momento per renderlo privato:

>> 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, dall'esterno della classe:

A.send :private, :m 
+0

Ciò renderà il metodo privato per tutti gli oggetti di quella classe e non 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 
Problemi correlati