Proc comparison

i'm having an issue where i need to compare 2 objects by comparing a
Proc which is stored in an instance var. however, everything i have
tried results in a false comparison.

simple example:

class Test
  attr :action

  def initialize(&block)
    @action = block_given? ? block : nil
  end

  def ==(obj)
    if obj.is_a?(Test)
      return @action.eql?(obj.action)
    end
  end
end

t1 = Test.new { puts "hello" }
t2 = Test.new { puts "hello" }

puts "comp: #{t1 == t2}"
puts "t1 action: #{t1.action}"
puts "t2 action: #{t2.action}"

output:

comp: false
t1 action: #<Proc:0x00025134@eql_test.rb:15>
t2 action: #<Proc:0x0002501c@eql_test.rb:16>

when the objects are created, i use the same block of code when i create
each instance, however, it obvious that from the comparison output they
aren't the same. my question, how do i get the comparison i'm looking
for?

···

--
Posted via http://www.ruby-forum.com/.

Even though the two blocks have the same contents, they aren't the same
block because they are written in different places in the file.

-mental

···

On Sat, 6 Oct 2007 04:22:50 +0900, Chris Hall <christopher.k.hall@gmail.com> wrote:

when the objects are created, i use the same block of code when i create
each instance, however, it obvious that from the comparison output they
aren't the same. my question, how do i get the comparison i'm looking
for?

Mental Guy wrote:

···

On Sat, 6 Oct 2007 04:22:50 +0900, Chris Hall > <christopher.k.hall@gmail.com> wrote:

when the objects are created, i use the same block of code when i create
each instance, however, it obvious that from the comparison output they
aren't the same. my question, how do i get the comparison i'm looking
for?

Even though the two blocks have the same contents, they aren't the same
block because they are written in different places in the file.

-mental

so then is there no way to compare the contents?
--
Posted via http://www.ruby-forum.com/\.

Even though the two blocks have the same contents, they aren't the same
block because they are written in different places in the file.

That's not the only thing. Proc#== returns false if the bindings differ as
well. So ...

If you want to compare regardless of the binding, you can check
Proc#same_body? in utilrb

http://utilrb.rubyforge.org/utilrb/classes/Proc.html

[~]% cat bla.rb
require 'utilrb/common'
def to_proc(&block)
    block
end

a, b = (1..2).map { to_proc { 10 } }
puts(a == b)
puts(a.same_body?(b))

[~]% ruby bla.rb
false
true

Sylvain

Not cleanly. Why do you want to?

-mental

···

On Sat, 6 Oct 2007 04:36:39 +0900, Chris Hall <christopher.k.hall@gmail.com> wrote:

so then is there no way to compare the contents?

Ah, good catch!

-mental

···

On Sat, 2007-10-06 at 04:49 +0900, Sylvain Joyeux wrote:

> Even though the two blocks have the same contents, they aren't the same
> block because they are written in different places in the file.
That's not the only thing. Proc#== returns false if the bindings differ as
well.

Mental Guy wrote:

so then is there no way to compare the contents?

Not cleanly. Why do you want to?

-mental

i'm building a system to manage 'tasks' where each task has an action
(block) that it does. this action is defined when the task is
initialized:

t = Task.new(:task1) { |task| puts "i am a task that does something" }

but i don't want the system to be able to have tasks that have the same
'action' as this would cause problems. i currently name the tasks and
can test if tasks have the same name, but that doensn't stop them from
having the same block of code (action).

···

On Sat, 6 Oct 2007 04:36:39 +0900, Chris Hall > <christopher.k.hall@gmail.com> wrote:

--
Posted via http://www.ruby-forum.com/\.

Chris Hall wrote:

but i don't want the system to be able to have tasks that have the same
'action' as this would cause problems. i currently name the tasks and
can test if tasks have the same name, but that doensn't stop them from
having the same block of code (action).

But even if the code block is textual different, it can have the same
semantics. E.g....

procs = [
  lambda{|i|(0..i-1)},
  lambda{|j|(0..j-1)},
  lambda{|*p|(0..p[0]-1)},
  lambda{|i|Range.new(0,i-1)}
]
procs.each{|p|p p.call(5)} # => outputs four times "0..4"

Yot try to compare semantic behaviour by comparing textual code
representation - this does not work.

Wolfgang Nádasi-Donner

···

--
Posted via http://www.ruby-forum.com/\.

but i don't want the system to be able to have tasks that have the same
'action' as this would cause problems. i currently name the tasks and
can test if tasks have the same name, but that doensn't stop them from
having the same block of code (action).

Define "action".

If "action" is "effect on the world", the blocks can change their own
internal state, in which case

Task() do
  puts "This changes external state"
  # This does not
  i = 0
end
Task() do
  puts "This changes external state"
  # This does not
  i = 1
end

would have the same action, but both blocks are different from a textual
point of view.

Sylvain

I see where everyone is going with this. I agree that even if it can be
done at some level, it's most likely pointless. I'm really not too
worried about trying to stop people (most likely just myself) from doing
any 'damage'.

an more detailed example of an action might be to do some db management
tasks. it's a situation where i wouldn't want 2 tasks doing the same
thing to be defined. but obviously there is no way to really stop it.

thanks to all that replied.

Sylvain Joyeux wrote:

···

but i don't want the system to be able to have tasks that have the same
'action' as this would cause problems. i currently name the tasks and
can test if tasks have the same name, but that doensn't stop them from
having the same block of code (action).

Define "action".

If "action" is "effect on the world", the blocks can change their own
internal state, in which case

Task() do
  puts "This changes external state"
  # This does not
  i = 0
end
Task() do
  puts "This changes external state"
  # This does not
  i = 1
end

would have the same action, but both blocks are different from a textual
point of view.

Sylvain

--
Posted via http://www.ruby-forum.com/\.