[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Proc comparison

Chris Hall

10/5/2007 7:23:00 PM

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-....

9 Answers

MenTaLguY

10/5/2007 7:31:00 PM

0

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



Chris Hall

10/5/2007 7:37:00 PM

0

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-....

Sylvain Joyeux

10/5/2007 7:49:00 PM

0

> 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...


[~]% 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

MenTaLguY

10/5/2007 10:18:00 PM

0

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?

Not cleanly. Why do you want to?

-mental


MenTaLguY

10/6/2007 1:51:00 AM

0

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.

Ah, good catch!

-mental

Chris Hall

10/6/2007 2:20:00 AM

0

Mental Guy wrote:
> 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?
>
> 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).
--
Posted via http://www.ruby-....

Wolfgang Nádasi-donner

10/6/2007 8:55:00 AM

0

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-....

Sylvain Joyeux

10/6/2007 9:05:00 AM

0

> 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

Chris Hall

10/6/2007 11:51:00 AM

0

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-....