Simple issue giving problems

Hello all,

I have a problem that may or may not be an easy fix. :slight_smile:

Given the following:

a=1
b=2

def swapper(dest,src)
dest,src=src,dest
end

swapper(a,b)
p [ a, b ]

Why are the values of the variables not swapped? Is there
a way to coerce ruby into doing a and b by using src and dest?

Any help is greatly appreciated.

Thanks,

Brad

Brad wrote:

a=1
b=2

def swapper(dest,src)
dest,src=src,dest
end

swapper(a,b)
p [ a, b ]

Well… given that the swap is only a one-liner, you really don’t need
to do the function call at all. However, I understand there is a deeper
issue here–sometimes you want to modify the parameters… What I
usually do is just return the modified parameters, like this:

def swaper( dest, src )
dest, src = src, dest
return [ dest, src ]
end

a, b = swapper( a, b )
p [ a, b ]

Ā·Ā·Ā·

–
Jamis Buck
jgb3@email.byu.edu

ruby -h | ruby -e ā€˜a=;readlines.join.scan(/-(.)[e|Kk(\S*)|le.l(…)e|#!(\S*)/) {|r| a << r.compact.first };puts ā€œ\n>#{a.join(%q/ /)}<\n\nā€ā€™

Hello all,

I have a problem that may or may not be an easy fix. :slight_smile:

Given the following:

a=1
b=2

def swapper(dest,src)
dest,src=src,dest
end

If you put it this way:

a=1
b=2

dest=a
src=b

dest,src=src,dest

It swaps dest and src. And I do not think you would expect a and b
being swapped as well as a result of this. Same with calling a method
as in your example. You cannot deal with variables’ addresses in Ruby
as in C.

swapper(a,b)
p [ a, b ]

Why are the values of the variables not swapped? Is there
a way to coerce ruby into doing a and b by using src and dest?

Any help is greatly appreciated.

Thanks,

Brad

Sincerely,
Gennady Bystritsky

Ā·Ā·Ā·

On Dec 11, 2003, at 14:37, Brad wrote:

sidenote:
I’ve playing with this idea:

Ā·Ā·Ā·

il Thu, 11 Dec 2003 18:34:26 -0400, Brad coish@hfx.eastlink.ca ha scritto::

Hello all,

I have a problem that may or may not be an easy fix. :slight_smile:

on a sidenote, I’ve been playing with:

def swapper(obj,a,b)
obj.instance_eval(ā€œ#{a},#{b}=#{b},#{a}ā€)
end

swapper(self,:a,:b)

but this does’nt work.

Anyway, if I do this:

p a
p b

self.instance_eval(ā€œ#{:a},#{:b}=#{:b},#{:a}ā€)
p a
p b

it works as expected (i.e. swaps the variables)

Some hints to explain me this ?

Ā·Ā·Ā·

il Thu, 11 Dec 2003 18:34:26 -0400, Brad coish@hfx.eastlink.ca ha scritto::

Hello all,

I have a problem that may or may not be an easy fix. :slight_smile:

Given the following:

Jamis Buck wrote:

Brad wrote:

a=1
b=2

def swapper(dest,src)
dest,src=src,dest
end

swapper(a,b)
p [ a, b ]

Well… given that the swap is only a one-liner, you really don’t need
to do the function call at all. However, I understand there is a deeper
issue here–sometimes you want to modify the parameters… What I
usually do is just return the modified parameters, like this:

def swaper( dest, src )
dest, src = src, dest
return [ dest, src ]
end

a, b = swapper( a, b )
p [ a, b ]

Thanks for your speedy response. You are quite correct as there is a
deeper issue, rather a larger project. I figured that 8 lines of code
were more illustrative than several hundred. :slight_smile:

I figured it couldn’t hurt to ask.

Thanks,
Brad

Gennady wrote:

Hello all,

I have a problem that may or may not be an easy fix. :slight_smile:

Given the following:

a=1
b=2

def swapper(dest,src)
dest,src=src,dest
end

If you put it this way:

a=1
b=2

dest=a
src=b

dest,src=src,dest

It swaps dest and src. And I do not think you would expect a and b
being swapped as well as a result of this. Same with calling a method
as in your example. You cannot deal with variables’ addresses in Ruby
as in C.

True, in the case you present I would not expect a and b to be altered.
But what I was wondering was if there were some way to allow
manipulation of

Ā·Ā·Ā·

On Dec 11, 2003, at 14:37, Brad wrote:

swapper(a,b)
p [ a, b ]

Why are the values of the variables not swapped? Is there
a way to coerce ruby into doing a and b by using src and dest?

Any help is greatly appreciated.

Thanks,

Brad

Sincerely,
Gennady Bystritsky

Hi!

  • Jamis Buck; 2003-12-12, 00:33 UTC:

def swaper( dest, src )
dest, src = src, dest
return [ dest, src ]
end

That code can be significantly improved:

def swapper(first, second)
return [second, first]
end

Using names dest, src would be okay for something like this:

def assigner(dest, src)
return [src, src]
end

Josef ā€˜Jupp’ SCHUGT

Ā·Ā·Ā·

–
http://oss.erdfunkstelle.de/ruby/ - German comp.lang.ruby-FAQ
http://rubyforge.org/users/jupp/ - Ruby projects at Rubyforge

gabriele renzi wrote:

on a sidenote, I’ve been playing with:

def swapper(obj,a,b)
obj.instance_eval(ā€œ#{a},#{b}=#{b},#{a}ā€)
end

swapper(self,:a,:b)

but this does’nt work.

Because the scope of the variables is different, I believe. The method
does not have access to local variables of the calling method. Even if
you use instance_eval, you will just have access to instance variables
of the given self, not local variables for any arbitrary local method
called on it further up the callchain.

Anyway, if I do this:

p a
p b

self.instance_eval(ā€œ#{:a},#{:b}=#{:b},#{:a}ā€)
p a
p b

it works as expected (i.e. swaps the variables)

Some hints to explain me this ?

a = 3
b = 5

Will not work, different scopes.

def swapper(obj,a,b)
obj.instance_eval(ā€œ#{a},#{b}=#{b},#{a}ā€)
end
swapper(self,:a,:b)
print a, b, ā€œ\nā€ #=> 35

Pass scope deliberately as a Proc.

def swapper2(a,b,&block)
eval(ā€œ#{a},#{b}=#{b},#{a}ā€, block)
end
swapper2(:a,:b){}
print a, b, ā€œ\nā€ #=> 53

You can do a lot of fancy (but ugly) things with the latter form. I tend
to rewrite it to pass arguments through the Proc, just to make it look
as ugly as it really is.

Pass scope deliberately as a Proc.

def swapper3(&block)
a,b = block.call
eval(ā€œ#{a},#{b}=#{b},#{a}ā€, block)
end
swapper3{[:a,:b]}
print a, b, ā€œ\nā€ #=> 35

HTH

Ā·Ā·Ā·

–
([ Kent Dahl ]/)_ ~ [ http://www.pvv.org/~kentda/ ]/~
))_student_/(( _d L b_/ Master of Science in Technology )
( __Ƶ|Ƶ// ) )Industrial economics and technological management(
_
/ƶ____/ (_engineering.discipline=Computer::Technology)

Brad wrote:

Gennady wrote:

Hello all,

I have a problem that may or may not be an easy fix. :slight_smile:

Given the following:

a=1
b=2

def swapper(dest,src)
dest,src=src,dest
end

If you put it this way:

a=1
b=2

dest=a
src=b

dest,src=src,dest

It swaps dest and src. And I do not think you would expect a and b
being swapped as well as a result of this. Same with calling a method
as in your example. You cannot deal with variables’ addresses in Ruby
as in C.

swapper(a,b)
p [ a, b ]

Why are the values of the variables not swapped? Is there
a way to coerce ruby into doing a and b by using src and dest?

Any help is greatly appreciated.

Thanks,

Brad

Sincerely,
Gennady Bystritsky

True, in the case you present I would not expect a and b to be altered.
But what I was wondering was if there were some way to allow
manipulation of

Sorry didn’t mean to send that one. :slight_smile: Hit wrong key sequence.

What I was trying to say was…

I was wondering if there were some way to allow manipulations of
function/methods parameters such that the calling processes variable
values would be modified.

As I understand it now this is not possible, though being new to Ruby I
thought it couldn’t hurt to ask.

Thanks for your response.

Regards,
Brad

Ā·Ā·Ā·

On Dec 11, 2003, at 14:37, Brad wrote:

ā€œJosef ā€˜Jupp’ SCHUGTā€ jupp@gmx.de schrieb im Newsbeitrag
news:20031212011325.GB1906@jupp%gmx.de…

Hi!

  • Jamis Buck; 2003-12-12, 00:33 UTC:

def swaper( dest, src )
dest, src = src, dest
return [ dest, src ]
end

That code can be significantly improved:

def swapper(first, second)
return [second, first]
end

usually

a,b = b,a

is sufficient.

Using names dest, src would be okay for something like this:

def assigner(dest, src)
return [src, src]
end

How do you want to use that method? I can’t see a use of this.

Regards

robert

irb(main):001:0> ary=%w(a b c d)
=> [ā€œaā€, ā€œbā€, ā€œcā€, ā€œdā€]
irb(main):002:0> def test(val)
irb(main):003:1> val[2] = 42
irb(main):004:1> end
=> nil
irb(main):005:0> test(ary)
=> 42
irb(main):006:0> ary
=> [ā€œaā€, ā€œbā€, 42, ā€œdā€]
irb(main):007:0>

Ā·Ā·Ā·

On Thu, 11 Dec 2003 20:26:53 -0400, Brad wrote:

I was wondering if there were some way to allow manipulations of
function/methods parameters such that the calling processes variable
values would be modified.

–
Simon Strandgaard

I don’t think this is possible. The only thing you can do is wrap vars
in a bigger datastruct (i.e. an array), then pass the object to your
swapper method.

Oh, and I think you can change variable bindings from within a Proc
object, if that helps :slight_smile:

Ā·Ā·Ā·

il Thu, 11 Dec 2003 20:26:53 -0400, Brad coish@hfx.eastlink.ca ha scritto::

Sorry didn’t mean to send that one. :slight_smile: Hit wrong key sequence.

What I was trying to say was…

I was wondering if there were some way to allow manipulations of
function/methods parameters such that the calling processes variable
values would be modified.

As I understand it now this is not possible, though being new to Ruby I
thought it couldn’t hurt to ask.

ā€œBradā€ coish@hfx.eastlink.ca schrieb im Newsbeitrag
news:6X7Cb.117608$PD3.5834673@nnrp1.uunet.ca…

True, in the case you present I would not expect a and b to be
altered.
But what I was wondering was if there were some way to allow
manipulation of

Sorry didn’t mean to send that one. :slight_smile: Hit wrong key sequence.

What I was trying to say was…

I was wondering if there were some way to allow manipulations of
function/methods parameters such that the calling processes variable
values would be modified.

Actually you don’t need that since you can always use a parallel
assignment:

a,b = b,a

foo[10], foo[7] = foo[7], foo[10]

bar[ā€œxā€], baz[ā€œeeeā€] = baz[ā€œeeeā€], bar[ā€œxā€]

As I understand it now this is not possible, though being new to Ruby I
thought it couldn’t hurt to ask.

Seems like you come from a perl background where such aliasings exist…

robert

Hi!

  • Robert Klemme; 2003-12-12, 22:34 UTC:

ā€œJosef ā€˜Jupp’ SCHUGTā€ jupp@gmx.de schrieb im Newsbeitrag
usually

a,b = b,a

is sufficient.

Of course. Unless the aim is an exercise in functional programming.

Using names dest, src would be okay for something like this:

def assigner(dest, src)
return [src, src]
end

How do you want to use that method? I can’t see a use of this.

I cannot see it, either. It was just the example involving least
changes where src and dest make sense.

Josef ā€˜Jupp’ SCHUGT

Ā·Ā·Ā·

–
http://oss.erdfunkstelle.de/ruby/ - German comp.lang.ruby-FAQ
http://rubyforge.org/users/jupp/ - Ruby projects at Rubyforge
...................................
Windows are best when they are ā€œunseenā€ – Chet Noll 27 Oct 2000

Brad wrote:

What I was trying to say was…

I was wondering if there were some way to allow manipulations of
function/methods parameters such that the calling processes variable
values would be modified.

As I understand it now this is not possible, though being new to Ruby I
thought it couldn’t hurt to ask.

No, it doesn’t hurt to ask.

There is a way of modifying the variable bindings in the calling method,
but it is not widely used. You need to create a ā€œreferenceā€ to the
variable and pass that into the swap function. I use a ā€œhelperā€
function ā€œrefā€ to create the reference …

Here’s an example …

require ā€˜reference’

def swap(a,b)
a.value, b.value = b.value, a.value
end

x = 10
y = 11

puts ā€œBEFORE: x = #{x}, y = #{y}ā€
swap(ref{:x}, ref{:y})
puts ā€œAFTER: x = #{x}, y = #{y}ā€

Note that those are curly braces, not parenthesis after ā€œrefā€. This
will print …

BEFORE: x = 10, y = 11
AFTER: x = 11, y = 10

Here’s the reference.rb file that you will need …

class Reference
def initialize(&block)
sym = block.call
fail ā€œBlock must yield symbolā€ unless Symbol === sym
@getter = eval ā€œproc { #{sym} }ā€, block
@setter = eval ā€œproc { |v| #{sym} = v }ā€, block
end
def value
@getter.call
end
def value=(v)
@setter.call(v)
end
end

def ref(&block)
Reference.new(&block)
end

Ā·Ā·Ā·

–
– Jim Weirich jweirich@one.net http://onestepback.org

ā€œBeware of bugs in the above code; I have only proved it correct,
not tried it.ā€ – Donald Knuth (in a memo to Peter van Emde Boas)

Jim Weirich wrote:

Brad wrote:

What I was trying to say was…

I was wondering if there were some way to allow manipulations of
function/methods parameters such that the calling processes variable
values would be modified.

As I understand it now this is not possible, though being new to Ruby I
thought it couldn’t hurt to ask.

No, it doesn’t hurt to ask.

There is a way of modifying the variable bindings in the calling method,
but it is not widely used. You need to create a ā€œreferenceā€ to the
variable and pass that into the swap function. I use a ā€œhelperā€
function ā€œrefā€ to create the reference …

Here’s an example …

require ā€˜reference’

def swap(a,b)
a.value, b.value = b.value, a.value
end

x = 10
y = 11

puts ā€œBEFORE: x = #{x}, y = #{y}ā€
swap(ref{:x}, ref{:y})
puts ā€œAFTER: x = #{x}, y = #{y}ā€

Note that those are curly braces, not parenthesis after ā€œrefā€. This
will print …

BEFORE: x = 10, y = 11
AFTER: x = 11, y = 10

Here’s the reference.rb file that you will need …

class Reference
def initialize(&block)
sym = block.call
fail ā€œBlock must yield symbolā€ unless Symbol === sym
@getter = eval ā€œproc { #{sym} }ā€, block
@setter = eval ā€œproc { |v| #{sym} = v }ā€, block
end
def value
@getter.call
end
def value=(v)
@setter.call(v)
end
end

def ref(&block)
Reference.new(&block)
end

Jim:

Thanks for the reply, it’s appreciated. I think this may be what I’m
looking for. I’ll give it a try and get back to you with the results.

Thanks,
Brad