2010-01-31 6 views
5

Мне нужно сделать некоторые методы экземпляра private после регистрации этого объекта в другом объекте.Сделать методы экземпляра приватными во время выполнения

Я не хочу замораживать объект, потому что он должен оставаться редактируемым, но с меньшей функциональностью. И я не хочу отменять методы, поскольку они используются внутри.

Что мне нужно что-то вроде:

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" 

Любые идеи?

ответ

4

Что публика и что секретна в классе. Но каждый объект может иметь свой собственный класс:

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) 

Но yuck. Рассмотрим эти альтернативы:

  • Просто сделайте этот метод общедоступным.
  • Исследуйте альтернативные проекты.
+0

Это отвечает моему сомнению: «Что такое публично, а что личное - за класс». Думаю, мне нужно изучить другие альтернативы. –

8

Вы можете вызвать метод private на имя метода в любое время, чтобы сделать его закрытым:

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

или вне класса:

A.send :private, :m 
+0

Это сделает метод закрытым для всех объектов этого класса, а не только одного. –

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 
Смежные вопросы