Passive Arguments

T

trans. (T. Onoma)

Since Ruby doesn't support signature-based method definitions, what good does
it do to throw errors on the wrong number of arguments? Seems to me, this
just makes the programmers job more difficult. What if Ruby nil'd unspecified
parameters and ignored extra parameters. Eg.

def ameth(a,b)
a.to_i + b.to_i
end

ameth #=> 0
ameth(1) #=> 1
ameth(1,2,3) #=> 3

Perhaps there is a problem with doing this that I don't see, but it's more in
line with Ruby's dynamic behavior. Testing is were such errors should be
caught, if indeed these are errors. This is the standard explanation one gets
about duck-typing after all. Why wouldn't it apply here as well? And it's not
like it can't be done either. As it stands, to achieve the same effect I must
conceive of it a bit differently as:

def ameth( *args )
args[0].to_i + args[1].to_i
end

So it's not like it should not be done. We do it all the time.

Okay so this leads me to my next thought about passive arguments. As you all
probably know I've been working on AOP for awhile and one thing to come up is
how to deal with the method signatures of advice. Since one advice method can
wrap multiple regular methods there's the problem of dealing with variant
signatures. For example look at this psuedo-code:

def x(a)
...

def y(a,b)
...

def w
puts "Advising"
super # calls the advised method
end

wrap :w => [ :x, :y ]

So #w wraps both #x and and #y. Obviously there's going to be a problem with
the arguments. The fix is of course to do 'def w(*args, &blk)' instead. And
indeed as far as wraps go one will ALWAYS end up having to do that. It would
be much nicer if one could do 'def w(a,b)' and it would still work --hence
the beginning of this post.

Also, since there will be occasions when the args won't matter it might be
nice too, if not specifying any parameters meant that they were simply passed
on through to super. In other words:

def w
puts "Advising"
super # calls the advised method
end

were exactly the same as doing:

def w(*args, &blk)
puts "Advising"
super(*args, &blk) # calls the advised method
end

and to actually change the interface one would have to do so explicitly, just
as one has to be with #super currently:

def w() # changes the interface
puts "Advising"
super # calls the advised method
end

What do you think?
T.
 
E

Esteban Manchado Velázquez

Hi,

Since Ruby doesn't support signature-based method definitions, what good does
it do to throw errors on the wrong number of arguments? Seems to me, this
just makes the programmers job more difficult. What if Ruby nil'd unspecified
parameters and ignored extra parameters. Eg.

def ameth(a,b)
a.to_i + b.to_i
end

ameth #=> 0
ameth(1) #=> 1
ameth(1,2,3) #=> 3

¡Arggh! Please don't. This is the Perl way, and I've had some good
headaches because of this, while refactoring code.
Perhaps there is a problem with doing this that I don't see, but it's more in
line with Ruby's dynamic behavior. Testing is were such errors should be
caught, if indeed these are errors. This is the standard explanation one gets
about duck-typing after all. Why wouldn't it apply here as well? And it's not
like it can't be done either. As it stands, to achieve the same effect I must
conceive of it a bit differently as:

def ameth( *args )
args[0].to_i + args[1].to_i
end

So it's not like it should not be done. We do it all the time.

But, IMHO, that's a pretty _rare_ need. If you need that, you can use
"*args" (as you say) or perhaps use optional parameters. But once you don't
raise an error when calling a method with an unexpected number of arguments,
you have _no automatic check_ for _most_ (again, IMHO) cases.

Regards,
 
T

trans. (T. Onoma)

On Sunday 16 January 2005 04:50 pm, Esteban Manchado Velázquez wrote:
| Hi,
|
| On Mon, Jan 17, 2005 at 12:32:08AM +0900, trans. (T. Onoma) wrote:
| > Since Ruby doesn't support signature-based method definitions, what good
| > does it do to throw errors on the wrong number of arguments? Seems to me,
| > this just makes the programmers job more difficult. What if Ruby nil'd
| > unspecified parameters and ignored extra parameters. Eg.
| >
| > def ameth(a,b)
| > a.to_i + b.to_i
| > end
| >
| > ameth #=> 0
| > ameth(1) #=> 1
| > ameth(1,2,3) #=> 3
|
| ¡Arggh! Please don't. This is the Perl way, and I've had some good
| headaches because of this, while refactoring code.


Ouch, A Spanish expletive! :) Could you elaborate on the problem arising from
refactoring? Thanks.
 
B

benny

trans. (T. Onoma) said:
In other words:

def w
puts "Advising"
super  # calls the advised method
end

were exactly the same as doing:

def w(*args, &blk)
puts "Advising"
super(*args, &blk)  # calls the advised method
end

I think this would be too much magic behind the scenes.
At the moment super ist behaving like just another method, i.e.
you can imagine how it behaves.

what if super may have arguments but you don't want to give any to it?
making super != super() is not an option.

in the most cases where I passed the same arguments to super that are given
to the method itself I figured out (after a while :) ) that I could have
made a better class design. IMHO it is more logical and usual to have no
equality in arguments.

benny
 
T

trans. (T. Onoma)

| > In other words:
| >
| > def w
| > puts "Advising"
| > super  # calls the advised method
| > end
| >
| > were exactly the same as doing:
| >
| > def w(*args, &blk)
| > puts "Advising"
| > super(*args, &blk)  # calls the advised method
| > end
|
| I think this would be too much magic behind the scenes.
| At the moment super ist behaving like just another method, i.e.
| you can imagine how it behaves.

Yes, well almost -- 'super' without args will pass on method args.

| what if super may have arguments but you don't want to give any to it?
| making super != super() is not an option.

Hmm...maybe I was not clear enough on this point (or I misunderstand) using
'super()' would NOT pass args to parent method, but just 'super' does pass
arguments --just as it is now. The change only comes in the 'def w', where no
arguments passes them through unchanged too.

| in the most cases where I passed the same arguments to super that are given
| to the method itself I figured out (after a while :) ) that I could have
| made a better class design. IMHO it is more logical and usual to have no
| equality in arguments.

Interesting thought, but it seems Matz thought it was common enough to have
special behavior on super, so I'm not sure.
 
B

benny

trans. (T. Onoma) wrote:

| making super != super() is not an option.

Hmm...maybe I was not clear enough on this point (or I misunderstand)
using 'super()' would NOT pass args to parent method, but just 'super'
does pass arguments --just as it is now.
Oh! I was sure that they are not passed by default, but I checked it and you
are right. it must be that I always use the explicit argument transfer or
did that behaviour change somewhere between 1.6 and 1.8.2?

but I really find it suprising that super != super() in contrast to every
other method.

learned a lesson today, thanks!

regards,

benny
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,737
Latest member
Georgeengab

Latest Threads

Top