代码之家  ›  专栏  ›  技术社区  ›  Filipe Miguel Fonseca

使实例方法在运行时私有

  •  5
  • Filipe Miguel Fonseca  · 技术社区  · 15 年前

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

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

    我需要的是:

    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"
    

    有什么想法吗?

    3 回复  |  直到 13 年前
        1
  •  4
  •   Wayne Conrad    15 年前

    什么是公共的,什么是私人的 每班 . 但是每个对象都可以有自己的类:

    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)
    

    但是,哎呀。考虑这些备选方案:

    • 只需将方法公开即可。
    • 探索替代设计。
        2
  •  8
  •   Mladen Jablanović    15 年前

    你可以调用方法 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
    
        3
  •  5
  •   Christopher Creutzig    15 年前
    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