Compare Content, Not Results, Procs

Using Ruby 1.9.2

Problem
Compare the contents, not the results, of the two processes. I understand that the results cannot be tested due to a stopping problem , but this is normal; I still don’t want to test the results.

for example

proc {@x == "x"} == proc {@x == "x"} => false # doh! 

This returns false because the objects inside the procs do not match.

My clumsy decision
I have a work solution that seems to do what I want, but does not really verify that proc is β€œequal” to what I put into it. In my particular case, the format of my procs will always be a logical test for instance variables like this:

 {@x == "x" && @y != "y" || @z == String} 

I wrote a method that dynamically builds classes and creates instance variables set for given values:

 def create_proc_tester(property_value_hash) new_class = Class.new.new new_class.class.class_eval do define_method(:xql?) { |&block| instance_eval &block } end property_value_hash.each do |key, value| new_class.instance_variable_set("@#{key}", value) end new_class end 

What can be used something like this:

 class Foo attr_accessor :block end foo = Foo.new foo.block = proc {@x == "x" && @y != "y" || @z == String} tester = create_proc_tester(:x => "x", :y => "y", :z => Fixnum) puts "Test #1: #{tester.xql? &foo.block}" tester = create_proc_tester(:x => "x", :y => "x", :z => String) puts "Test #2: #{tester.xql? &foo.block}" > Test #1: false > Test #2: true 

.
.
This is all wonderful and wonderful, but I want to know if there is a more efficient, more meta-method that actually checks the contents of proc, and not just the work that solves my specific problem; something that could be used to test any process.

I thought there might be a way to use the Ruby parser to compare something, but I have no idea how to do this. I am studying this now, but thought that I would try to see if anyone here had done this before and knows how to do it. This may be a dead end, although due to the dynamic nature of Ruby, but now that I look now.

+4
source share
2 answers

If you are using Ruby 1.9, you can use the sourcify gem.

 $ irb > require 'sourcify' => true > a = proc {@x == "x"} => #<Proc: 0x9ba4240@ (irb):2> > b = proc {@x == %{x}} => #<Proc: 0x9ba23f0@ (irb):3> > a == b => false > a.to_source == b.to_source => true > RUBY_VERSION => "1.9.2" 

We also encountered the ParseTree / Ruby 1.9 incompatibility problem in my company.

+4
source
 $ sudo gem install ruby2ruby ParseTree require 'parse_tree' require 'ruby2ruby' require 'parse_tree_extensions' # All of these are the same: proc { puts 'a' }.to_ruby # => "proc { puts(\"a\") }" lambda { puts "a" }.to_ruby # => "proc { puts(\"a\") }" Proc.new { puts %{a} }.to_ruby # => "proc { puts(\"a\") }" # If you need to do this with classes: class Bar; define_method(:foo) { 'a' }; end puts Ruby2Ruby.new.process(Unifier.new.process(ParseTree.translate(Bar))) # will print this: # class Bar < Object # def foo # "a" # end # end 
+2
source

All Articles