On 7 February 2013 10:39, Rob M. [email protected] wrote:
Every other language I’ve worked in, C, Perl, Python, Java…the way you
call a function with arguments is: func(arg1, arg2, arg3). In Python you
can have variable args and keyword args specified as (*args, **kwargs),
but in general you define the arguments that a function expects, and
then pass those arguments between parentheses.
Give or take a few other var-args tricks. Remember C has stdarg.h and
allows function signatures like:
void func(...);
And Java has special array syntactic sugar:
public static void func(Object... args)
And PHP almost completely ignores the variables named in the function
signature, because you can always use func_num_args() and
func_get_args()
etc.
Ruby allows non-parenthetical args, the same as shell script (e.g.
Bash).
Technically perl doesn’t require parentheses either, except that
functions
in perl expect a list of parameters, and perl lists use parentheses,
etc.
etc. Upshot: $thingy->foo
is also a function call in perl.
end
and not only get the args specified between the parens in *args, but
also still pass the block and “yield” it, is a very new, and foreign,
concept for me.
If it helps, you can also define it as:
def func(*args, &a_block)
if you want to make explicit the fact that there is (or expects to be) a
block. It also gives you direct access to the block, so you can poke it
and stuff.
this
arbitrary value and returning it slightly modified…so don’t get hung
up on it) is evaluated prior to being passed as an argument to func. But
since there’s no block, I get the LocalJumpError.
To the first remark: this is the same as any other programming
language.
For example in Java:
func("this", "is", "a", "test", return_value("something"));
…will execute the ‘return_value’ function first, then pass its result
as
the final parameter to ‘func’.
As an aside to the second: You can get around/preempt the LocalJumpError
by
wrapping yield
thus:
def func(*args)
args.each { |a| puts a }
yield if block_given?
end
Not necessarily what you want to do here, but handy to know.
func “this”, “is”, “a”, “test”, { return_value(“something”) }
SyntaxError: compile error
(irb):111: odd number list for Hash
from (irb):111
This is is also somewhat obvious because it isn’t treating the {} as
defining a block but attempting to define a hash…That’s because I
haven’t “formally” defined the arguments, so the interpreter assumes
everything is supposed to be an argument and not a block.
That would happen irrespective of how you define the function
parameters.
SyntaxErrors happen when ruby is parsing and interpreting the file, not
when it’s executing. A curly brace that follows a comma is always
interpreted as the start of a Hash literal.
Since blocks are special, “out-of-band” parameters, you don’t need a
comma
to distinguish them from the other args. However, since curly-brace
block
syntax looks a lot like Hash literal syntax, you need to give the parser
a
bit more help in this case (i.e. by explicitly wrapping the “real” args
in
parens, then giving the block.)
func(“this”, “is”, “a”, “test”) { return_value(“something”) }
this
is
a
test
=> “This is the returning value: something”
This is still the odd one for me that now (sort-of) makes sense but
would NOT be allowed in any language I’ve used in the past. So it’s
going to take some getting used to…
This is true, but only because those other languages don’t have blocks.
Note that the following calls are equivalent:
func("this", "is", "a", "test") { return_value("something") }
func "this", "is", "a", "test" do
return_value "something"
end
my_block = proc { return_value("something") }
func "this", "is", "a", "test", &my_block
my_block = proc { return_value("something") }
func("this", "is", "a", "test", &my_block)
The third and fourth versions are the call-site equivalent of the def func(*args, &a_block)
definition I mentioned above.
I hope this helps shed a little light on the issue, and gives you some
pointers for further research.
–
Matthew K., B.Sc (CompSci) (Hons)
http://matthew.kerwin.net.au/
ABN: 59-013-727-651
“You’ll never find a programming language that frees
you from the burden of clarifying your ideas.” - xkcd