2010-01-31 36 views
5

我需要在将对象注册到另一个对象后使某些实例方法变为私有。在运行时将实例方法设为私有

我不想冻结对象,因为它必须保持可编辑状态,只有较少的功能。因为它们在内部使用,所以我不想取消这些方法。

我需要的是这样的:

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) 

但是,考虑这些替代方案:

  • 只需使该方法公开。
  • 探索替代设计。
+0

这回答了我的疑问:“什么是公开的,什么是私人是每班。”。猜猜我必须探索其他选择。 – 2010-01-31 17:19:11

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

这会使该方法的所有对象都是私有的,而不仅仅是一个。 – 2010-01-31 14:14:10

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 
相关问题