Submitted by chemdog (Sun Feb 29 08:02:03 UTC 2004)
As an example
h = Net::HTTP.new(website, 80) response, data = h.get(webpage, nil)
Did I put the response and data variables in the right order? ( Yes, this time.) Functionality for ensuring that the right results get into the correct variable is needed.
Using the previous example the method definition would change to
def [response, data] get(page, header=nil)the old user code still works, but additionally the call site can include argument glue. The examples for this are
h = Net::HTTP.new(website, 80) [:response response, :data data] = h.get(webpage, nil) [:data data2] = h.get(webpage2, nil) [:response response3] = h.get(webpage3, nil) [:data data4, :response response4] = h.get(webpage4, nil)
In the second and third examples, the response2 and data3 are discarded at the call site.
Every method name could be prefixed by an return argument name array. At method invocation time, each named return element is set to nil. Whenever an assignment occurs within a method to a return argument name, the assignment is bound to the returned value. A return statement by itself, assembles the return array using the current values of the named return argument variables. A return statement with arguments, has its arguments expanded to match the format of the return call. A short array is padded with nil entries. A long array is truncated to fit within the values. The last statement, if it returns a value, is used as if it were a return statment passing that value, and if it doesn't return a value, is treated as an empty return.
The named argument list can use a star to indicate the remaining arguments. As in "def [stuff, stuff2, *rest] variable_length_method". Additional entries in a long return are packed into the last argument.
Call-sites can use named glue to bind a named return argument to a call-site array position. Additionally, the call-site can bind a star argument in any position; however, it receives an array of the remainder of the arguments.
For example,
[:stuff stuff, :rest rest, :stuff2 stuff2] = variable_length_method # receives "elem1","elem3-elemN","elem2"This change shouldn't break any old code, however the old interpreter would be unable to handle the new method def's and glue bindings.
Comments | Current voting | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
RCRchive copyright © David Alan Black, 2003-2005.
Powered by .
As with many such things, this comes down to a trade-off (leaving aside the question of how easy or hard it would be to implement; I suspect hard-to-impossible, though I'm not sure). The trade-off is: not having to worry about argument order, in exchange for what looks to me like really considerable amounts of visual clutter. My view is that it would not be worth it; the problem isn't that serious, and methods that return a long list of result values should probably be redesigned (e.g., as iterators). -- David Black
You could do this with your own code by returning a Hash of Symbols to return values. Making this a language change in unnecessary given that it can be done in Ruby in an clean and elegant way. -- memmove
It is no harder to implement than Named Call Arguments(Hash Arguments, Key-Value Calls) -- which has been proposed elsewhere. The same procedure generally can be used for either task. The examples above, perhaps are not the right way to implement this. Maybe a new Ruby-System-Class called CallingHash (or something similar), can be created to wrap arguments for calls and returns. Even if not, the visual clutter isn't mandatory. All the old code still works; so libraries that should be redesigned can still be used. I am definitely not married to a syntax, or execution of this feature; though it needs to retain a few this format's features.
The biggest advantage to this method, as opposed to wrapping a return value in an object and 'nil'-ing a return value, is for JITRuby and compiledRuby (hopefully, JIT will be integrated into Rite). This format has potentially easier work for these compilers. Unused arguments are easily seen, and a special version of that method can be created for that and similar call-sites. Wrapping the object, or making a return hash, can create a compiler optimizer nightmare. This identically functioning code undergoes no enhancement until call-graph, inlining, and recursion optimizations are enabled. --chemdog
I don't think that this offers any advantage whatsoever. Basically, you're asking for a default "hash" return, as memmove pointed out that you can do:
All of a sudden, you have a hash that returns what you want.
Additionally, I don't know of many compiled languages that allow for "overloading" based on the return value (one noteable exception is Delphi). In Java, I can't do:
I think the case for this needs to be made a bit better, as there are ways in Ruby to get around the problem. Remember as well that the named keyword setup is simply going to be syntactic sugar around an already extant behaviour (the use of hashes with Symbols as keys), not adding a new behaviour, so there's almost no cost to this. -- Austin Ziegler (cleaned up display: 20040408)