Использование Ruby 1.9.2
Задача
Сравните содержание, а не результаты двух процедур. Я понимаю, что результаты не могут быть проверены из-за проблемы остановки 1009 *, но это нормально; Я все равно не хочу проверять результаты.
Например
proc {@x == "x"} == proc {@x == "x"} => false # doh!
Это возвращает false, потому что объекты внутри процов не совпадают.
Мой неуклюжий раствор
У меня есть обходное решение, которое вроде как делает то, что я хочу, но на самом деле это не проверяет, что процесс "равен" тому, что я в него положил. В моем конкретном случае формат моих процедур всегда будет логическим тестом для переменных экземпляра, таких как:
{@x == "x" && @y != "y" || @z == String}
Я написал метод, который динамически создает классы и создает переменные экземпляра с заданными значениями:
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
Что можно использовать примерно так:
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
.
.
Это все замечательно и замечательно, но я хочу знать, есть ли лучший, более мета-способ сделать это, который на самом деле проверяет содержимое процесса, а не просто работу, которая решает мою конкретную проблему; что-то, что можно использовать для проверки любого процесса.
Я думал, что может быть способ использовать синтаксический анализатор Ruby для сравнения, но я понятия не имею, как. Я исследую это сейчас, но подумал, что попробую посмотреть, делал ли кто-нибудь здесь это раньше и знает ли как. Это может быть тупик, хотя из-за динамической природы Ruby, но это то, что я сейчас смотрю.