在 Ruby 的对象中重写 `not` 的定义
rewriting definition of `not` in Ruby's Object
对这个 RubyMonk 示例的作用感到非常困惑。 class Not
应该是 return 一个能够反转对 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
传递参数时,它是如何 "travel" 的?它转到 not
方法,之后创建 class Not
的新实例并将其传递给该实例?
method_missing
需要什么?在这种情况下可能缺少什么方法?当缺少方法时它会做什么?它只是被告知不要将参数发送给 @original
就这样吗?
method_missing
在 Not
class 中才是真正的魔法。这些是场景:
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?
方法。如果 none 实现了 smith?
方法,那么 Ruby 将以相同的方式调用 method_missing
,并且您已经为 [=14] 更改了 method_missing
的行为=] class.
现在它会得到@original
也就是person
对象并调用person对象的方法,这个Person实例对象已经实现了这个方法,等结果出来了我们就否定结果。因此,如果调用 not.smith?
的人的 smith?
方法 return 为真,则 return 为假,因为 smith?
方法 return 为真,我们否定value 并得到 false,如果它 returns false,当我们取反时你得到 true。
编辑:
Person
是Object
的扩展,但是Not
和Person
没有联系,Person
不是扩展Not
Not
没有扩展 Person
.
Not
是 Object
里面的 class 并且它没有名为 smith?
的方法,Person
的实例对象得到了 smith?
方法。这就是为什么它没有在 Not
实例对象上找到 smith?
方法,然后它从继承链中调用 method_missing
,而你已经为 [=] 实现了 method_missing
14=] class 它采用您调用 Object
class 的 not
方法并从 Not
class 创建实例对象的对象参数为 Person
实例对象。
编辑2:
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
编辑 3:
另请查看一些参考文献 method_missing
的工作原理
回答您的问题 #1:
in what ways does this change the built-in definition of method not
?
a) 不是,因为 b) not
不是方法,它是关键字,因此它的定义已融入语言规范。
更准确地说:not
关键字被转换为对方法 !
的调用,就像 !
运算符一样,因此以下所有三个都是等价的:
not foo
!foo
foo.!
对这个 RubyMonk 示例的作用感到非常困惑。 class Not
应该是 return 一个能够反转对 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
传递参数时,它是如何 "travel" 的?它转到not
方法,之后创建class Not
的新实例并将其传递给该实例? method_missing
需要什么?在这种情况下可能缺少什么方法?当缺少方法时它会做什么?它只是被告知不要将参数发送给@original
就这样吗?
method_missing
在 Not
class 中才是真正的魔法。这些是场景:
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?
方法。如果 none 实现了 smith?
方法,那么 Ruby 将以相同的方式调用 method_missing
,并且您已经为 [=14] 更改了 method_missing
的行为=] class.
现在它会得到@original
也就是person
对象并调用person对象的方法,这个Person实例对象已经实现了这个方法,等结果出来了我们就否定结果。因此,如果调用 not.smith?
的人的 smith?
方法 return 为真,则 return 为假,因为 smith?
方法 return 为真,我们否定value 并得到 false,如果它 returns false,当我们取反时你得到 true。
编辑:
Person
是Object
的扩展,但是Not
和Person
没有联系,Person
不是扩展Not
Not
没有扩展 Person
.
Not
是 Object
里面的 class 并且它没有名为 smith?
的方法,Person
的实例对象得到了 smith?
方法。这就是为什么它没有在 Not
实例对象上找到 smith?
方法,然后它从继承链中调用 method_missing
,而你已经为 [=] 实现了 method_missing
14=] class 它采用您调用 Object
class 的 not
方法并从 Not
class 创建实例对象的对象参数为 Person
实例对象。
编辑2:
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
编辑 3:
另请查看一些参考文献 method_missing
的工作原理
回答您的问题 #1:
in what ways does this change the built-in definition of method
not
?
a) 不是,因为 b) not
不是方法,它是关键字,因此它的定义已融入语言规范。
更准确地说:not
关键字被转换为对方法 !
的调用,就像 !
运算符一样,因此以下所有三个都是等价的:
not foo
!foo
foo.!