何时将self用于Ruby类

时间:2019-06-19 22:52:31

标签: ruby

当我们在class << self块中创建方法以及定义常规方法时,有人可以帮助我区分一下。

我在某处看到了这样的代码,但我不太清楚它们的用例

class Foo
  def initialize
  end

  def bar
  end

  class << self
    def foobar
    end
  end
end

3 个答案:

答案 0 :(得分:2)

您可能需要阅读Ruby的实例和类方法。 但就我个人而言,

class Foo
  class << self
    def foobar
    end
  end
end

代替

class Foo
  def self.foobar
  end
end

无论何时我想添加一些类级别的属性,或将方法设为私有等作为

class Foo
  private
  def self.foobar
  end
end

的工作方式不同
class Foo
  class << self
    private
    def foobar
    end
  end
end

答案 1 :(得分:2)

class块中定义的“普通”方法是实例方法

class Foo
  def bar
  end
end

class << self块内的class中定义的方法是类方法

class Foo
  class << self
    def baz
    end
  end
end

实例方法可用于给定类的任何实例:

foo = Foo.new
foo.bar

可以在类上直接调用类方法:

Foo.baz

尝试在类上调用实例方法,反之亦然,将导致错误:

Foo.bar #=> NoMethodError: undefined method `bar' for Foo:Class
foo.baz #=> NoMethodError: undefined method `baz' for #<Foo:0x00007ffe20055a20>

定义类方法的另一种方法是在方法名称前加上self.

class Foo
  def self.baz
  end
end

您也可以在class块之外定义它们,尽管这种情况很少见:

def Foo.baz
end

或者类似地:

class << Foo
  def baz
  end
end

请注意,以这种方式定义方法不仅限于类。您可以将方法添加到任意对象,例如:

o = Object.new

def o.hello
  "hello from o"
end

o.hello
#=> "hello from o"

或通过:

class << o
  def hello
    "hello from o"
  end
end

内部,这些方法被添加到对象的 singleton类中。这是一个特殊用途的类,用于仅保存该实例的方法:

o.singleton_class.instance_methods(false)
#=> [:hello]

对于上面的Foo类:

Foo.instance_methods(false)                 #=> [:bar]
Foo.singleton_class.instance_methods(false) #=> [:baz]

从技术上讲,类方法只是在类的单例类上定义的实例方法。

答案 2 :(得分:0)

感谢您分享您的知识。总结一下我从这本link

中读到的内容

什么时候使用分类方法?

Class Method是属于该类的一部分功能,但不依赖于任何特定的单个实例。

例如

Product.find(1)
Product.new(params[:product])

何时使用实例方法?

当需要对类的特定实例进行操作时,可以使用实例方法。

通常是当功能涉及实例的身份时,例如在对象上调用属性或调用行为。

例如

@product.save
@product.name