Reputation: 31
The comparison operator outlined here (shown below) on ruby 2.2.0 is really just a comparison of the Proc#call result with another object. The documentation reads:
proc === obj → result_of_proc
Invokes the block with obj as the proc's parameter like #call. It is to allow a proc object to be a target of when clause in a case statement.
What I'm looking for is something to the effect of:
a = Proc.new { puts 'hi' }
b = Proc.new { puts 'hi' }
a == b
# => true
Can this somehow be done?
Trying to solve for a cache invalidation problem on this gist (code shown below). If there's already a cache file, then any change to the Kinescope block will be ignored.
module Kinescope
def self.film(reel,&block)
file_name = "kinescoped_#{reel}.ml"
begin
Marshal.load(File.read(file_name))
rescue
data = yield
File.open(file_name,'w') do |f|
f.write(Marshal.dump(data))
end
data
end
end
end
def time_consuming_calculation
sleep 60
true
end
test = Kinescope.film :big_data do
# 'film' gigantic data here
result = []
File.foreach('big_file.txt') do |line|
result << line if time_consuming_calculation
end
result
end
Upvotes: 3
Views: 136
Reputation: 9495
You could try to decompose procs back into Ruby source code strings using ruby2ruby
, then compare them. However, to handle some subtle differences such as variable names that do not affect behavior you may want to get a syntax tree instead and write some more sophisticared comparison.
Bear in mind that this approach is a comparison of code, not the functions' effect. It will not be able to detect two functions that do the same thing if they are written differently.
Upvotes: 0
Reputation: 369536
This is called the Function Problem and is equivalent to solving the Halting Problem. Think about it. If this were possible, then you could solve the Halting Problem like this:
infinite_loop = -> { nil while true }
some_program == infinite_loop # => true
Ergo, it is impossible to algorithmically determine whether two programs compute the same function.
Upvotes: 2