2010-01-31 5 views
5

Je dois rendre certaines méthodes d'instance privées après avoir enregistré cet objet dans un autre objet.Rendre les méthodes d'instance privées à l'exécution

Je ne veux pas geler l'objet car il doit rester modifiable, mais avec moins de fonctionnalités. Et je ne veux pas annuler les méthodes puisqu'elles sont utilisées en interne.

Ce que je besoin est quelque chose comme:

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" 

Toutes les idées?

Répondre

4

Ce qui est public et ce qui est privé est par classe. Mais chaque objet peut avoir sa propre 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) 

Mais beurk. Considérez ces alternatives:

  • Simplifiez la méthode publique.
  • Explorez d'autres conceptions.
+0

Cela répond à mes doutes: "Ce qui est public et ce qui est privé est par classe.". Je suppose que je dois explorer d'autres alternatives. –

8

Vous pouvez appeler la méthode private sur le nom de la méthode à tout moment pour le rendre privé:

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

ou, en dehors de la classe:

A.send :private, :m 
+0

Cela rendra la méthode privée pour tous les objets de cette classe et pas seulement un. –

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 
Questions connexes