真的很困惑这个RubyMonk示例的作用。 class Not
应该返回一个能够将调用反转为Object#not
的对象。
class Object
def not
Not.new(self)
end
class Not
def initialize(original)
@original = original
end
def method_missing(sym, *args, &blk)
!@original.send(sym, *args, &blk)
end
end
end
class Person
def initialize(name)
@name = name
end
def smith?
@name == "Smith"
end
end
这就是测试的方式
puts Person.new("Smith").not.smith?
puts Person.new("Ziggy").not.smith?
我不明白的是
not
的内置定义?not
时,它是如何"旅行"?它转到not
方法,之后创建了class Not
的新实例并将其传递给该实例?method_missing
需要什么?在这种情况下可能会缺少什么方法?当有方法丢失时它会怎么做?只是告诉他们不要将论据发送到@original
那就是它了吗?答案 0 :(得分:3)
回答你的问题#1:
这会以什么方式改变方法
not
的内置定义?
a)它没有,因为b)not
不是一个方法,它是一个关键字,因此它的定义被烘焙到语言规范中。
更准确地说:not
关键字转换为方法!
的调用,就像!
运算符一样,因此以下所有三个都是等效的:
not foo
!foo
foo.!
答案 1 :(得分:2)
method_missing
课程中的 Not
是真正的魔力。这是场景:
Person.new("Smith") # you create new person
Person.new("Smith").not # calls method #not on the person object instance
# the method #not will create new instance of the class Not and passing self as argument
# passing the person on which you have called the method
# then the initialize method of the Not class gets called
# because you want to create new object of the Not class and
# @original is the person on which you have called the method #not
Person.new("Smith").not.smith? # will call method #smith? on the Not object instance
到目前为止发生的事情
person = Person.new("Smith")
not_class_object = person.not
not_class_object.smith? # there is no method named #smith? in the Not class
如果不存在任何方法,则检查所有层次结构,并查看继承链中的任何内容是否已实现smith?
方法。如果没有实现smith?
方法,则Ruby将以相同的方式调用method_missing
,并且您已更改method_missing
类Not
的行为。
现在它将获得@original
person
对象并调用person对象上的方法,此Person实例对象已实现该方法,当结果出现时,我们将取消结果。因此,如果smith?
方法为调用not.smith?
的人返回true将返回false,因为smith?
方法返回true我们否定该值并获取false,如果它返回false,则当我们否定时你明白了。
编辑:
Person
是Object
的扩展名,但Not
与Person
之间没有关联,Person
未延伸Not
和{ {1}}未展开Not
。
Person
是Not
内的类,它没有名为Object
的方法,smith?
的实例对象获得了Person
方法。这就是为什么它没有在smith?
实例对象上找到smith?
方法,然后从继承链调用Not
,并且为{{method_missing
实现了method_missing
1}}类,它使用Not
类not
方法调用的对象,并从Object
类创建实例对象,参数为Not
实例对象。< / p>
EDIT2:
Person
EDIT3:
还查看一些参考class NotPerson
...
# some code
...
end
p1 = Person.new("Smith")
p2 = Person.new("Ziggy")
p3 = NotPerson.new("something")
p1.smith? # -> true
p2.smith? # -> false
p3.smith? # Error there is no method named #smith? in NotPerson class
not_p1 = p1.not
not_p2 = p2.not
not_p3 = p3.not
not_p1.smith? # -> false
# Because there is no method #smith? on #not class, and #method_missing is called
not_p1.smith? # is eqivavlent to
!(p1.smith?)
not_p2.smith? # -> true
not_p3.smith? # Error there is no method #smith? definedin NotPerson class
如何工作