了解Ruby类与实例方法

ran*_*its 2 ruby

我有以下代码:

#!/usr/bin/ruby

class Person
  def self.speak
    p = self.new
    puts "Hello"
    p.chatter
  end

private

  def chatter
    puts "Chattering"
  end
end

p = Person.new
Person.speak
Run Code Online (Sandbox Code Playgroud)

我想私聊,只能在p ...内访问,但我希望p能够在类方法中访问它.有没有更好的方法来设计这个,所以公众无法获得聊天,但像self.speak这样的"工厂"方法可以调用聊天?

Way*_*rad 8

在Ruby 1.8.7中,"send"绕过了对调用私有方法的常规保护:

#!/usr/bin/ruby1.8

class Person

  def self.speak
    puts "Hello"
    new.send(:chatter)
  end

  def speak
    puts "Hello"
    puts chatter
  end

  private

  def chatter
    puts "Chattering"
  end

end

Person.speak        # => Hello
                    # => Chattering
Person.new.speak    # => Hello
                    # => Chattering
Run Code Online (Sandbox Code Playgroud)

但是,只要让类方法完成所有工作,并且实例方法遵循类方法,你可以在没有任何巫术的情况下实现你想要的东西:

class Person

  def self.speak
    puts "Hello"
    puts "Chatter"
  end

  def speak
    self.class.speak
  end

end
Run Code Online (Sandbox Code Playgroud)

如果您有多个这样的转发方法,那么为您制作一个帮助方法可能会很方便:

module DelegateToClass

  def delegate_to_class(name)
    define_method(name) do |*args|
      self.class.send(name, *args)
    end
  end

end

class Person

  extend DelegateToClass

  def self.speak
    puts "Hello"
    puts "Chatter"
  end
  delegate_to_class :speak

end
Run Code Online (Sandbox Code Playgroud)

内置模块Forwardable也可以这样做:

require 'forwardable'

class Person

  extend Forwardable

  def self.speak
    puts "Hello"
    puts "Chatter"
  end

  def_delegator self, :speak

end
Run Code Online (Sandbox Code Playgroud)

def_delegator 还绕过了对私人方法的保护.