如何在Ruby中访问私有类方法?

时间:2015-01-09 11:13:07

标签: ruby-on-rails ruby

给出Ruby中的一个类:

class MyClass
  def self.my_class_method
    puts "class method"
  end

  private

  def my_method
    puts "regular method"
  end

  private_class_method :my_class_method
end

要访问私有方法,我可以在类对象上调用.send(:my_method),但这对类方法有什么作用?

4 个答案:

答案 0 :(得分:12)

你应该这样做:

class MyClass
  def self.my_class_method
    puts "class method"
  end

  private

  def my_method
    puts "regular method"
  end

  private_class_method :my_class_method
end

# to call class method
MyClass.send :my_class_method # => class method
# to call instance method
MyClass.new.send :my_method # => regular method

在Ruby中,类也是对象,因此您也可以在类上调用#send方法。

在Ruby中,您可以将私有类方法定义为

class MyClass
  class << self
    private 

    def my_class_method
      puts "class method"
    end
  end
end

或使用此方法:private_class_method

答案 1 :(得分:1)

仅供参考,这不是您创建私有类方法的方式。

class A
  private

  def self.foo
    "foo"
  end
end

A.foo # => "foo"

要创建私有类方法,您需要使用private_class_method

class A
  def self.foo
    "foo"
  end

  private_class_method :foo
end

A.foo # => private method `foo' called for A:Class

答案 2 :(得分:1)

首先,MyClass.send(:my_method)不起作用。您必须将其发送到实例:MyClass.new.send(:my_method)

然后,您的my_class_method并非真正私密 Ruby的private语义与您在其他语言中使用的语义略有不同。由于Ruby允许您在选择时绕过封装,private只是意味着方法只能被隐式地调用 ,而不会向实际对象发送消息。

例如:

class Example
  def test
    'foobar'
  end

  def hello
    puts test        # implicit receiver
    puts self.test   # explicit receiver
  end
end

这一切都很好,但为什么这对你的问题很重要?
因为您在my_class_method上明确声明了self。这样做绕过 private修饰符,该方法是公开的。这意味着您可以通过以下方式调用它:

MyClass.my_class_method

如果你真的需要private类方法,那么你可以在元类上定义它们:

class MyClass

  class << self

    private

    def my_class_method
      puts "class method"
    end
  end


  private

  def my_method
    puts "regular method"
  end

end

这会使my_class_method 实际上私有,并强制您使用以下任意方式调用它:

MyClass.send :my_class_method
MyClass.class_exec { my_class_method }
MyClass.class_eval { my_class_method }
MyClass.class_eval "my_class_method"

答案 3 :(得分:1)

没有类方法这样的东西。类方法只是类的单例方法。但是也没有单身方法这样的东西。单例方法只是单例类的实例方法。因此,类方法只是类的单例类的实例方法。

由于没有类方法,只有实例方法,你已经知道该怎么做了:

  

要访问私有方法,我可以在类对象上调用.send(:my_method),但这对类方法有什么作用?