![]() |
A simple question regarding ruby method argument
Hi,
I am new to ruby and am learning it now. Can anyone point me how to pass argument to method by reference? I mean that the methods/function able to change the value of the argument. I am running windows using win32ole and 1 of the method need to pass in an argument and the argument will modify by the win32ole methods. But I don't know how to pass argument by reference. Thanks in advance. -- Posted via http://www.ruby-forum.com/. |
Re: A simple question regarding ruby method argument
> Can anyone point me how to pass
> argument to method by reference? I mean that the methods/function able > to change the value of the argument. Values are always passed by reference: irb(main):011:0> class Test irb(main):012:1> attr_accessor :a irb(main):013:1> end irb(main):014:0> def modify x irb(main):015:1> x.a="hello" irb(main):016:1> end irb(main):017:0> t = Test.new irb(main):018:0> t.a="there" irb(main):019:0> modify t irb(main):020:0> t.a => "hello" what doesn't work is passing in a parameter `x`, assigning a new value to x within a function and expecting that assignment to be 'transfered' outside the function scope: def modify x x=2 # this doesn't work, because it modifies the reference and not # the referenced value end tmp=1 modify tmp # doesn't work as you'd like, tmp is still 1 puts tmp => 1 If you're familiar with Java, it's more or less the same behaviour. -Tim |
Re: A simple question regarding ruby method argument
Tim Becker wrote:
> tmp=1 > modify tmp # doesn't work as you'd like, tmp is still 1 > puts tmp > => 1 > Hi Tim, If I have a method which will need to modify the parameter passing to it, how do I going to do that in ruby? In c we can pass in reference using the & or c# using ref or out. But I am not sure Ruby have this kind of keyword or not. The method I use is define by the com dll and I calling it using win32ole. Thanks. -- Posted via http://www.ruby-forum.com/. |
Re: A simple question regarding ruby method argument
> If I have a method which will need to modify the parameter passing to
> it, how do I going to do that in ruby? Maybe you could post the source of the method so we can figure out how to get around the problems you're experiencing. > In c we can pass in reference But if you pass in a pointer in C and assign a new value to the pointer itself (instead of changing what is being pointed at) you won't change the pointer variable outside of method scope either... In c: #include <stdio.h> void test( int * x) { x=0; // modifies the reference, doesn't have the intended effect } void test2 (int * x) { *x=0; // modifies the referenced values, works. } int main (int argc, char * argv[]) { int i=1; printf("%d\n", i); test (&i); printf("%d\n", i); test2 (&i); printf("%d\n", i); } -Tim |
Re: A simple question regarding ruby method argument
Hi --
On 3/14/07, Shin guey Wong <sgwong513@hotmail.com> wrote: > Hi, > > I am new to ruby and am learning it now. Can anyone point me how to pass > argument to method by reference? I mean that the methods/function able > to change the value of the argument. I am running windows using win32ole > and 1 of the method need to pass in an argument and the argument will > modify by the win32ole methods. But I don't know how to pass argument by > reference. You're (almost) always passing references around anyway. Ruby doesn't have references to references; all references are exactly one degree away from the object to which they refer. When you do this: def amend(s) s << " there." end str = "Hi" amend(str) you've changed the original string object: puts str # Hi there. because str holds a reference to that object, and s in the method is a copy of str (i.e., a copy of the reference, not the string). David -- Q. What is THE Ruby book for Rails developers? A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf) Q. Where can I get Ruby/Rails on-site training, consulting, coaching? A. Ruby Power and Light, LLC (http://www.rubypal.com) |
Re: A simple question regarding ruby method argument
I am trying to write a method that changes the value of two arguments.
Stripped to the barest essentials, something like this: def munge(a) a = a + 1 end zot = 3 print zot, "\n" # this should (and does) print '3' munge(zot) print zot, "\n" # this should print '4'. We wouldn't be here now if it did! Now, if I try the amend method given by David A. Black, it works as expected. But it's passing a string object, not an integer. Surely there is a way to give a method _something_ so that it can return values to the caller. Of course, if I only ever had a single value to return, I could make it the return value, but that's just begging the question. Thanks in advance, John -- Posted via http://www.ruby-forum.com/. |
Re: A simple question regarding ruby method argument
Hi --
On Sat, 25 Aug 2007, John Dearden wrote: > I am trying to write a method that changes the value of two arguments. > Stripped to the barest essentials, something like this: > > def munge(a) > a = a + 1 > end > > zot = 3 > print zot, "\n" # this should (and does) print '3' > munge(zot) > print zot, "\n" # this should print '4'. We wouldn't be here now if it > did! > > Now, if I try the amend method given by David A. Black, it works as > expected. But it's passing a string object, not an integer. > > Surely there is a way to give a method _something_ so that it can return > values to the caller. Of course, if I only ever had a single value to > return, I could make it the return value, but that's just begging the > question. Since integers are immutable (luckily!), and local variables are local, you can't change an integer object via a reference copied to a method. If it helps, I can assure you that you would *not* want this to happen. It would be very weird if my local variables bindings were at the mercy of methods that I called. What you're really looking for is an object container, and local variables don't really work that way. For container semantics you really need to use containers. You could do something like: def munge(a) [*a][0] += 1 end z = 3 y = *munge(z) and so forth. David -- * Books: RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242) RUBY FOR RAILS (http://www.manning.com/black) * Ruby/Rails training & consulting: Ruby Power and Light, LLC (http://www.rubypal.com) |
Re: A simple question regarding ruby method argument
David A. Black wrote:
...stuff deleted... > Since integers are immutable (luckily!), and local variables are > local, you can't change an integer object via a reference copied to a > method. If it helps, I can assure you that you would *not* want this > to happen. It would be very weird if my local variables bindings were > at the mercy of methods that I called. > > What you're really looking for is an object container, and local > variables don't really work that way. For container semantics you > really need to use containers. You could do something like: First, thanks for the quick answer. That was unexpected. Unfortunately I can't say I understand the part of your response I quoted above, other than that it says, "Nope, you can't do what you're trying to do. Unless you're working with strings, which are somehow different." The "local variables _bindings_" bit implies to me this has something to do with Ruby's underlying storage that I have not yet grasped. I'm still thinking of a 'local variable' as really some chunk of memory, and the way the bits are set in that memory mean something in the context of my program. If I pass that location to a subprogram, and know that it's going to put something else in it, that's good. I can think of examples where I would like my subprogram to modify the local variables of the calling code. For instance, I have two points, and I want to calculate m and b for the formula of a line, as in y = m * x + b. I would be inclined to write a subprogram calc_m_b(x1, y1, x2, y2, var m, var b) (in Pascalese). I could do what amounts to the same thing with two functions, one returning m and the other b, but that seems sort of silly in this case. I could design an object that represented a line in some fashion, and let it hold m and b, but that's not always what you'd want, either. Maybe I'm not thinking in terms of objects enough yet? Thanks again, John -- Posted via http://www.ruby-forum.com/. |
Re: A simple question regarding ruby method argument
Hi --
On Sat, 25 Aug 2007, John Dearden wrote: > David A. Black wrote: > ...stuff deleted... >> Since integers are immutable (luckily!), and local variables are >> local, you can't change an integer object via a reference copied to a >> method. If it helps, I can assure you that you would *not* want this >> to happen. It would be very weird if my local variables bindings were >> at the mercy of methods that I called. >> >> What you're really looking for is an object container, and local >> variables don't really work that way. For container semantics you >> really need to use containers. You could do something like: > > First, thanks for the quick answer. That was unexpected. > > Unfortunately I can't say I understand the part of your response I > quoted above, other than that it says, "Nope, you can't do what you're > trying to do. Unless you're working with strings, which are somehow > different." > > The "local variables _bindings_" bit implies to me this has something to > do with Ruby's underlying storage that I have not yet grasped. I'm > still thinking of a 'local variable' as really some chunk of memory, and > the way the bits are set in that memory mean something in the context of > my program. If I pass that location to a subprogram, and know that it's > going to put something else in it, that's good. > > I can think of examples where I would like my subprogram to modify the > local variables of the calling code. For instance, I have two points, > and I want to calculate m and b for the formula of a line, as in y = m * > x + b. I would be inclined to write a subprogram calc_m_b(x1, y1, x2, > y2, var m, var b) (in Pascalese). I could do what amounts to the same > thing with two functions, one returning m and the other b, but that > seems sort of silly in this case. I could design an object that > represented a line in some fashion, and let it hold m and b, but that's > not always what you'd want, either. > > Maybe I'm not thinking in terms of objects enough yet? I agree my answer was sort of "You can't do the thing you just said you can't do" :-) But that is sort of how it is. It's axiomatic in Ruby that local variables are local. By "bindings" I mean: def x(a) a = 3 # a is bound to 3 end a = 1 # *this* (different) a is bound to 1 x(a) puts a # still 1 The call to x does not change the existing binding of a. The only kind of change you can do in a situation like this is when a variable is bound to a mutable object -- or, more accurately, a variable contains a reference to a mutable object (since basically Ruby variables traffic in references). That's where you get into things like: def add_to_array(a) a.push("New element") end array = [1,2,3] add_to_array(array) p array # [1,2,3,"New element"] If I use 'a' instead of 'array' for my array, the fact that add_to_array also uses 'a' is just coincidence. There's no connection between the two. It just happens that the identifier 'a' is used in two local scopes to handle references to the same object. The usual patterns you see in Ruby are either container-based, object-based (where you have an object with an attribute; you pass the object into the method and it does something to the attribute), or assignment-based but in the same scope: def change_me(a) a + 2 end a = 1 a = change_me(a) # a is now 3 I've pushed the assignment out of the method -- where it doesn't have any effect except to set or change the method's local variables -- into the calling context. That way, I can do whatever I want with my identifiers in each scope. David -- * Books: RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242) RUBY FOR RAILS (http://www.manning.com/black) * Ruby/Rails training & consulting: Ruby Power and Light, LLC (http://www.rubypal.com) |
Re: A simple question regarding ruby method argument
On 8/24/07, John Dearden <john.dearden@earthlink.net> wrote:
> I am trying to write a method that changes the value of two arguments. > Stripped to the barest essentials, something like this: > > def munge(a) > a = a + 1 > end > > zot = 3 > print zot, "\n" # this should (and does) print '3' > munge(zot) > print zot, "\n" # this should print '4'. We wouldn't be here now if it > did! > > Now, if I try the amend method given by David A. Black, it works as > expected. But it's passing a string object, not an integer. > > Surely there is a way to give a method _something_ so that it can return > values to the caller. Of course, if I only ever had a single value to > return, I could make it the return value, but that's just begging the > question. or you can return more than one value def munge(a, b) return a + 1, b - 2 end q = 4 r = 9 q, r = munge(q, r) > > Thanks in advance, > John > -- > Posted via http://www.ruby-forum.com/. > > |
| All times are GMT. The time now is 08:59 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.