0

下面的“疯狂”有实际应用吗?

似乎这是一种ted总是能够让自己回到这个世界的方式,人们会认为他们正在与ted他们期望以某种方式行事并达到一定年龄的人交谈......但他并没有按照这种方式行事他描绘自己,并向某人谎报他的年龄。

当一个对象被返回并且您检查该对象代表什么以及能够做什么时,什么“诡计”是可能的......但实际上,该对象在返回之前以另一种方式行事并且能够做其他事情。

class Person

  def age
    21
  end

  def who_am_i?
    puts "I am #{self} / #{object_id} and I am #{age} years old"
    self
  end
end


ted = Person.new

def ted.singleton_who_am_i?       

    class << self
      def age
        0
      end
    end

    puts "I am #{self} / #{object_id} and I am #{age} years old"
    self
end

puts ted.who_am_i? == ted.singleton_who_am_i?



>> I am #<Person:0x100138340> / 2148123040 and I am 21 years old
>> I am #<Person:0x100138340> / 2148123040 and I am 0 years old
>> true
4

2 回答 2

0

http://andrzejonsoftware.blogspot.ca/2011/02/dci-and-rails.html

在 DCI 中,您的数据模型会根据使用它的上下文获得不同类型的行为。通常它是用 object.extend 完成的,但这几乎就是你在上面所做的——利用元类。

另一个例子(可能也是为什么事情会这样)是类在 ruby​​ 中的工作方式。如果你说

class Foo
end

这和说的一样

Foo = Class.new
end

这意味着您正在做的是将类 Class 的新实例分配给常量。当您在该类上定义一个方法时,您不希望它应用于类 Class 的所有实例,您只希望它在您定义的类上。所以当你说

class Foo
  def self.bar
  end
end

就是这么说的

class Foo
end

def Foo.bar
end

这与您在问题中所说的完全相同

(抱歉,如果不清楚)

于 2012-04-26T06:08:04.083 回答
0

Ruby 是一种非常动态的语言,可让您在运行时将代码注入对象。它有一些很好的用途,但它也会使代码很难调试和理解。

查询对象以修改该对象的方法完全违反直觉。没有人会期望调用 who_am_i 来修改对象。

另一方面,替换这样的方法可以使单元测试类变得非常简单。

如果您想测试该类在不同年龄段的行为方式,您可以在测试之前注入类似的代码。

于 2012-04-26T06:10:20.363 回答