了解Ruby类与实例方法

时间:2010-04-20 02:07:45

标签: 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

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

2 个答案:

答案 0 :(得分:8)

在Ruby 1.8.7中,“发送”绕过了对调用私有方法的常规保护:

#!/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

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

class Person

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

  def speak
    self.class.speak
  end

end

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

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

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

require 'forwardable'

class Person

  extend Forwardable

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

  def_delegator self, :speak

end

def_delegator也绕过了对私人方法的保护。

答案 1 :(得分:1)

有很多方法可以做到这一点。一种方法是实例化新实例并在实例上调用#speak方法的类方法。

class Person
  def self.speak
    new.speak
  end

  def speak
    puts "Hello"
    chatter
  end

  private

  def chatter
    puts "Chattering"
  end
end

然后你可以在类或实例上下文中调用它:

p = Person.new
p.speak
# ...or...
Person.speak