【问题标题】:Make instance methods private in runtime在运行时将实例方法设为私有
【发布时间】:2010-01-31 13:06:18
【问题描述】:

在另一个对象中注册该对象后,我需要将一些实例方法设为私有。

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

我需要的是这样的:

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"

有什么想法吗?

【问题讨论】:

    标签: ruby access-specifier


    【解决方案1】:

    您可以随时在方法名称上调用方法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
    

    【讨论】:

    • 这将使该类的所有对象的方法私有,而不仅仅是一个。
    【解决方案2】:
    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
    

    【讨论】:

      【解决方案3】:

      什么是公开的,什么是私有的,每个类。但是每个对象都可以有自己的类:

      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)
      

      但是很糟糕。考虑以下替代方案:

      • 只需将方法公开即可。
      • 探索替代设计。

      【讨论】:

      • 这回答了我的疑问:“什么是公开的,什么是私有的是每个班级的。”。我想我必须探索其他替代方案。
      猜你喜欢
      • 2011-03-11
      • 1970-01-01
      • 2013-03-16
      • 2011-01-09
      • 2018-12-29
      • 2013-11-12
      • 1970-01-01
      • 2010-10-01
      • 2022-01-22
      相关资源
      最近更新 更多