为类的实例定义一个方法。

3
如何在类的实例上定义一个方法,使该方法只适用于该实例而不适用于其他实例?
请有人提供此功能的用例。

最常见的用例是所谓的类方法。在Ruby中,一个类就是一个对象。如果你想为单个类(而不是所有类)添加一个方法,你需要一种在每个对象级别上定义该方法的方式(对象即为类)。像 def Date.today ; ... ; end 这样的语句与 def obj.foo ; ... ; end 是相同的。 - Stefan
2
另一种观点是:它允许基于原型的方法,其中对象是主要实体,不需要(命名的)类。您只需从空白的“Object”实例开始,并向其添加方法以使其响应相应的消息。设置好对象后,您可以通过对其进行“克隆”来创建基于该对象(或原型)的新对象。 - Stefan
2
不是答案,但我想说看到有人先学习Ruby核心并试图理解它,而不是直接跳进Rails,这真是令人耳目一新。在我看来,太多人从Rails开始,然后再试着从中“搞清楚”Ruby,这可能是一个非常艰难的过程。 - engineersmnky
如果你想理解Ruby和类/实例的区别,你可能需要学习一些有关Eigenclass的基础知识。 - tadman
2个回答

3
在对象上定义一个单例方法会给你一个带有一些新属性的对象。就是这样,不多也不少。
当然,你可以通过另一种方式实现同样的效果——创建一个具有所需属性并进行实例化的新类,混合一个添加必要行为的模块。在大多数实际情况下,你可能会选择这样做。
但是,想象一下测试场景,例如您需要模拟某个对象的方法(当然,RSpec框架提供了更好的方法来完成这项工作,但仍然)。或者你正在REPL中调试代码,并想要模拟某个方法(例如,避免不必要的副作用)。在这种情况下,定义一个单例方法是最简单(最快)的方法来完成任务。
只是不要将这个“特性”看作一个单独的特性。因为它不是。它只是Ruby对象模型工作的一个结果,关注后者即可。我强烈推荐阅读这本书来深入了解...

1

类方法是在类本身上调用的,这就是为什么在方法声明中它总是会声明为def self.class_method_name.

而实例方法是在类的特定实例上调用的(而不是类本身),它们像普通方法一样声明,即def instance_method_name.

例如:

class Car
  def self.class_method
    puts "It's a class method"
  end

  def instance_method
    puts "It's an instance method"
  end
end


Car.class_method => "It's a class method"
Cat.instance_method => undefined method 'instance_method' for Car:Class

Car.new.instance_method => "It's an instance method"
Car.new.class_method => undefined method 'class_method' for Car:Class

关于用例,这里有一个来自Rails的例子:

class Car < ApplicationRecord
  belongs_to :owner
  has_many :passengers

  def self.get_cars(owner) # This is a class method
    Car.includes(:passengers).where(owner: owner).order(created_at: :desc)
  end
end

使用Car.get_cars(owner)方法,您可以根据自己的逻辑获取所有车辆。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接