这让我疯了,经过大量的回顾,我在这里发帖。
我想知道指向同一个Proc的两个变量是否指向同一个Proc。 我确定它一定是我没有得到的东西,例如为什么所有这些都返回假?
class LambdaFunctions
def self.LambdaFunction1
lambda { |t| t ** 2}
end
end
a = LambdaFunctions.LambdaFunction1
b = LambdaFunctions.LambdaFunction1
puts LambdaFunctions.LambdaFunction1
puts a
puts b
puts a == b
puts a === b
puts a.eql?(b)
puts a.equal?(b)
puts a == LambdaFunctions.LambdaFunction1
puts a === LambdaFunctions.LambdaFunction1
puts a.eql?(LambdaFunctions.LambdaFunction1)
puts a.equal?(LambdaFunctions.LambdaFunction1)
谢谢马克,你说得更清楚了。
在之前它每次都返回新对象,所以相等?功能永远不会回归真实。两个lambda在功能上是相同但不是同一个对象。
因此,如果您创建一个版本,然后在方法中将其返回,则可以测试它的身份。
以下内容更有意义,并且符合我的预期。
class LambdaFunctions
@lambda1 = lambda { |t| t ** 2}
@lambda2 = lambda { |t| t ** 2}
def self.LambdaFunction1
@lambda1
end
def self.LambdaFunction2
@lambda2
end
end
func1 = LambdaFunctions.LambdaFunction1
func2 = LambdaFunctions.LambdaFunction1
func3 = LambdaFunctions.LambdaFunction2
puts func1.equal?(func2) # true
puts func1.equal?(func3) # false
puts func1.equal?(LambdaFunctions.LambdaFunction1) # true
puts func3.equal?(LambdaFunctions.LambdaFunction1) # false
puts func3.equal?(LambdaFunctions.LambdaFunction2) # true
答案 0 :(得分:6)
虽然lambda 有效等效,但每次调用LambdaFunctions.LambdaFunction1
都会返回lambda的新实例。只有通过身份,而不是价值,触发是有意义的,因为实际上不可能确定程序的等价。
我的意思是,如果可以根据他们所做的事情确定触发器是等效的,那么lambda { 3 }
和lambda { 1 + 2 }
将是等效的。使用lambdas比这更复杂,确定等价基本上需要halting problem的解决方案。
要确定等效身份(根据评论),请参阅Object#equal?:
与
==
不同,equal?
方法永远不应被子类覆盖:它用于确定对象标识(即a.equal?(b)
iffa
是同一个对象作为b
)。
如果你确实需要a
和b
成为同一个对象,那么每次都需要返回相同的lambda;这意味着您需要将lambda分配给LambdaFunctions
类中的实例变量,并返回 。
ruby-1.9.1-p378 > class LambdaFunctions
ruby-1.9.1-p378 ?> @func1 = lambda { |t| t ** 2 }
ruby-1.9.1-p378 ?> def self.LambdaFunction1
ruby-1.9.1-p378 ?> @func1
ruby-1.9.1-p378 ?> end
ruby-1.9.1-p378 ?> end
=> nil
ruby-1.9.1-p378 > a = LambdaFunctions.LambdaFunction1
=> #<Proc:0x0000010099e370@(irb):10 (lambda)>
ruby-1.9.1-p378 > b = LambdaFunctions.LambdaFunction1 # same address as a
=> #<Proc:0x0000010099e370@(irb):10 (lambda)>
ruby-1.9.1-p378 > a == b
=> true
答案 1 :(得分:0)
使用equals
方法进行相等可能不是您想要的,如果被比较的两个对象引用同一个对象,它只会返回true
。我认为在这种情况下你可能更喜欢==
。
我创建了一个proc_extensions gem来获取proc或lambda的来源。您可以使用它来比较两个proc或lambda的来源,如下所示:
require 'proc_extensions'
Proc.instance_eval { include ProcExtensions::Source }
class LambdaFunctions
@lambda1 = lambda { |t| t ** 2}
@lambda2 = lambda { |t| t ** 2}
def self.LambdaFunction1
@lambda1
end
def self.LambdaFunction2
@lambda2
end
end
func1 = LambdaFunctions.LambdaFunction1.source
func2 = LambdaFunctions.LambdaFunction1.source
func3 = LambdaFunctions.LambdaFunction2.source
func1 == func2 # => true
func1 == func3 # => true
func1 == LambdaFunctions.LambdaFunction1.source # => true
func3 == LambdaFunctions.LambdaFunction1.source # => true
func3 == LambdaFunctions.LambdaFunction2.source # => true