当我们在class << self
块中创建方法以及定义常规方法时,有人可以帮助我区分一下。
我在某处看到了这样的代码,但我不太清楚它们的用例
class Foo
def initialize
end
def bar
end
class << self
def foobar
end
end
end
答案 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