信任刚刚返回的对象?

时间:2012-04-26 05:48:38

标签: ruby self

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

似乎这是ted始终能够让自己回归世界的一种方式,人们会认为他们正在与ted人交谈,他们希望以某种方式行事并成为某个年龄......但他并没有按照自己描绘的方式行事,并且正在向某个人撒谎。

当一个对象被返回并且你检查那个对象代表什么并且有能力时,'trickery'是可能的......但实际上该对象在返回之前是以另一种方式行事并能够做其他事情。

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

2 个答案:

答案 0 :(得分: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

这与您在问题中谈论的原则完全相同

(对不起,如果不清楚的话)

答案 1 :(得分:0)

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

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

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

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