簡體   English   中英

如何在Ruby中訪問私有類方法?

[英]How to access private class methods in 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) ,但是這對於類方法有什么用呢?

你應該做:

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

僅供參考,這不是您創建私有類方法的方式。

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

首先, 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"

沒有類方法這樣的東西。 類方法只是類的單例方法。 但是也沒有單身方法這樣的東西。 單例方法只是單例類的實例方法。 因此,類方法只是類的單例類的實例方法。

由於沒有類方法,只有實例方法,你已經知道該怎么做了:

要訪問私有方法,我可以在類對象上調用.send(:my_method) ,但是這對於類方法有什么用呢?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM