Ruby中创建类方法的不同方法

时间:2016-10-08 20:15:01

标签: ruby class methods syntax class-method

示例1:

class Dog
  def self.class_method
    :another_way_to_write_class_methods
  end
end

def test_you_can_use_self_instead_of_an_explicit_reference_to_dog
  assert_equal :another_way_to_write_class_methods, Dog.class_method
end

示例2:

class Dog
  class << self
    def another_class_method
      :still_another_way
    end
  end
end

def test_heres_still_another_way_to_write_class_methods
  assert_equal :still_another_way, Dog.another_class_method
end

我是否知道在Ruby中编写类方法的哪种方式是首选?为什么?是否存在一种优先于另一种情况的情况?

2 个答案:

答案 0 :(得分:5)

您询问了创建类方法的不同方法。这是一些。

class A
  def self.a
    "A"
  end
end
A.a #=> "A"
class B
  class << self
    def b
      "B"
    end
  end
end
B.b #=> "B"
class C
  singleton_class.class_eval do
    def c
      "C"
    end
  end
end
C.c #=> "C"
module M
  def m
    "M"
  end
end

class D
  extend M
end
D.m #=> "M"
class E
  class << self
    include M
  end
end
E.m #=> "M"
class F
  singleton_class.instance_eval do
    define_method(:f) do
      "F"
    end
  end
end
F.f #=> "F"

如果要动态创建:f

class F
end
F.singleton_class.instance_eval do
   define_method(:f) do
     "F"
   end
end

或变体:

F.singleton_class.instance_eval "define_method(:f) { 'F' }"
F.f #=> "F"
class Class
  def k
    "K"
  end
end

class G
end
G.k #=> "K"

这里的问题是Class的所有实例方法(包括:k)都可以被所有类用作(类)方法,因为类是Class的实例({ {1}})。

H.class#=>Class

这个很有意思。 class Object def o "O" end end class H end H.o #=> "O" H.new.o #=> "O" ObjectClass)的祖先,因此Class.ancestors #=> [Class, Module, Object, Kernel, BasicObject]Class继承实例方法:o。因此(从前一种情况),Object:o的类方法。但是,H也是HObject)的子类,因此H.superclass #=> Object会继承实例方法H

至于哪个是“最好的”,这取决于。如果要创建几个类方法,大多数将使用Object#:o。如果需要大量数字,我会使用AD。如果要动态创建类方法,B或某些变体。但是,我无法想象我会使用FG的情况。

答案 1 :(得分:3)

this ruby style guide表示class << self语法“在您必须定义许多类方法时可行且方便。”

他们有使用这两个版本的代码示例,所以对于使用一个版本而言,肯定没有广泛的社群共识。

我个人使用def self.my_method来减少缩进