[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

local variables vs. methods

Henrik Schmidt

5/26/2007 1:31:00 PM

Hi there,

I've been playing around with Ruby for a while, but there's still one
particular feature of the language that doesn't make sense to me. If you
write a class containing a method and a class with the same name, the
interpreter will pick the variable over the method, unless you
specifically tells it not to. For example,

class Foo

def output
puts foo # "foo"
foo = 42
puts foo # 42
puts self.foo # "foo"
puts foo() # "foo"
end

def foo
"foo"
end

end

Foo.new.output

As seen above, there are several ways of getting around this, but this
is the question: Why is this behaviour useful? As I see it, it's bad
practice to give a method and a local variable the same name. At least I
can't think of an example where it would make sense. Why not simply
disallow this or at least have the interpreter issue a warning?

Best regards,
Henrik Schmidt
16 Answers

Hakusa@gmail.com

5/26/2007 2:51:00 PM

0

If a language stops you from doing something just because it's bad
practice, then the language is treating you like an idiot. What if I
wanted to override a function for a little while? I could assign it a
new value and use the same methods of a different class!

Henrik Schmidt

5/26/2007 4:00:00 PM

0

Hakusa@gmail.com wrote:
> If a language stops you from doing something just because it's bad
> practice, then the language is treating you like an idiot.

Fine, so don't stop be. Warn me that I'm doing something which is
probably a programmer error 99% of the time. Ruby stops me from all
sorts of things I can do in Perl. I think that's a good thing, since I'm
a horrible Perl programmer :)

>What if I
> wanted to override a function for a little while? I could assign it a
> new value and use the same methods of a different class!
>

Then you'll just override it. My question is, why would you want to
override a method with a variable? I have no problem with overloading a
method with another method, and neither should the interpreter.

Hakusa@gmail.com

5/26/2007 4:22:00 PM

0

> >What if I
> > wanted to override a function for a little while? I could assign it a
> > new value and use the same methods of a different class!
>
> Then you'll just override it. My question is, why would you want to
> override a method with a variable? I have no problem with overloading a
> method with another method, and neither should the interpreter.

What if instead of printing bar's output with puts bar, bar was a
local variable so it printed an error message alerting the user that
something wrong has happened.

I don't really know when it would be useful, but who knows. What if
someday I find that it is?

Henrik Schmidt

5/26/2007 4:33:00 PM

0

Henrik Schmidt wrote:
> Hakusa@gmail.com wrote:
>> If a language stops you from doing something just because it's bad
>> practice, then the language is treating you like an idiot.
>
> Fine, so don't stop be. Warn me that I'm doing something which is
> probably a programmer error 99% of the time. Ruby stops me from all
> sorts of things I can do in Perl. I think that's a good thing, since I'm
> a horrible Perl programmer :)
>
>> What if I
>> wanted to override a function for a little while? I could assign it a
>> new value and use the same methods of a different class!
>>
>
> Then you'll just override it. My question is, why would you want to
> override a method with a variable? I have no problem with overloading a
> method with another method, and neither should the interpreter.

In fact, now that I think about it, how would you override a method from
one class with a variable in another class making use of this feature?

Last year I asked a question also pertaining to variable/method
ambiguity. At the time I thought one solution might be to force
parentheses on all methods. I got some very good answers why this was a
bad idea. The best answer was, IMHO, that it would make the private and
protected methods look strange and unintuitive. The implication of that
was of course, that you could create methods like private and protected
and have them behave as keywords or even overload these methods and have
them behave differently. I wasn't aware of that of the time, and I think
that's pretty cool.

Basically, I'm looking for the same thing here. What possible use can
there be for this feature? I don't get it.

Henrik Schmidt

5/26/2007 4:40:00 PM

0

Hakusa@gmail.com wrote:
>>> What if I
>>> wanted to override a function for a little while? I could assign it a
>>> new value and use the same methods of a different class!
>> Then you'll just override it. My question is, why would you want to
>> override a method with a variable? I have no problem with overloading a
>> method with another method, and neither should the interpreter.
>
> What if instead of printing bar's output with puts bar, bar was a
> local variable so it printed an error message alerting the user that
> something wrong has happened.

I think a nicer way of doing this would be to overload bar with a method
that throws an exception.

> I don't really know when it would be useful, but who knows. What if
> someday I find that it is?

If you can do the same thing with a method I don't see the problem.
Also, it would eliminate (or at least warn) when you do this:

def foo
42
end

puts foo # -> 42
foo = 24 if false;
puts foo # -> nil

I would like to be warned in this situation, as it's fairly likely I'm
doing something I didn't intend to do.

Hakusa@gmail.com

5/26/2007 4:43:00 PM

0

> Basically, I'm looking for the same thing here. What possible use can
> there be for this feature? I don't get it.

Thought of something:
I still don't really know how to use a proc or anything like that, but
it seems to me ...

proc = Proc.new # How you initialize a proc makes me think that a proc
is just another type of a variable.

So you could overload your method with a variable so that a proc which
does a different thing is called. If you can see why overloading with
a method could be good, you can see why this could be good.

But note that I'm not all that experienced either, so I could be
entirely wrong. But I still think that someday, it just might be
helpful.

Henrik Schmidt

5/26/2007 5:01:00 PM

0

Hakusa@gmail.com wrote:
>> Basically, I'm looking for the same thing here. What possible use can
>> there be for this feature? I don't get it.
>
> Thought of something:
> I still don't really know how to use a proc or anything like that, but
> it seems to me ...
>
> proc = Proc.new # How you initialize a proc makes me think that a proc
> is just another type of a variable.

It is.

>
> So you could overload your method with a variable so that a proc which
> does a different thing is called. If you can see why overloading with
> a method could be good, you can see why this could be good.

Well, if you would like proc to do something different then just assign
a different Proc to it. Also, I don't think you can overload proc with a
method. The variable always wins.

> But note that I'm not all that experienced either, so I could be
> entirely wrong. But I still think that someday, it just might be
> helpful.

I can't think of any way, contrived or otherwise, that would make this
helpful, but I'm fairly inexperienced myself. Let's say I accept your
argument. Why not issue a warning?

Trans

5/26/2007 6:26:00 PM

0



On May 26, 1:05 pm, Henrik Schmidt <no.s...@nspmaxyz.abc> wrote:
> Hak...@gmail.com wrote:
> >> Basically, I'm looking for the same thing here. What possible use can
> >> there be for this feature? I don't get it.
>
> > Thought of something:
> > I still don't really know how to use a proc or anything like that, but
> > it seems to me ...
>
> > proc = Proc.new # How you initialize a proc makes me think that a proc
> > is just another type of a variable.
>
> It is.
>
>
>
> > So you could overload your method with a variable so that a proc which
> > does a different thing is called. If you can see why overloading with
> > a method could be good, you can see why this could be good.
>
> Well, if you would like proc to do something different then just assign
> a different Proc to it. Also, I don't think you can overload proc with a
> method. The variable always wins.
>
> > But note that I'm not all that experienced either, so I could be
> > entirely wrong. But I still think that someday, it just might be
> > helpful.
>
> I can't think of any way, contrived or otherwise, that would make this
> helpful, but I'm fairly inexperienced myself. Let's say I accept your
> argument. Why not issue a warning?


class X
def foo; "blah"; end

def bar
if something_or_another
foo = "big blah"
end
puts foo
end
end

T.


Trans

5/26/2007 6:31:00 PM

0



On May 26, 9:35 am, Henrik Schmidt <no.s...@nspmaxyz.abc> wrote:
> Hi there,
>
> I've been playing around with Ruby for a while, but there's still one
> particular feature of the language that doesn't make sense to me. If you
> write a class containing a method and a class with the same name, the
> interpreter will pick the variable over the method, unless you
> specifically tells it not to. For example,
>
> class Foo
>
> def output
> puts foo # "foo"
> foo = 42
> puts foo # 42
> puts self.foo # "foo"
> puts foo() # "foo"
> end
>
> def foo
> "foo"
> end
>
> end
>
> Foo.new.output
>
> As seen above, there are several ways of getting around this, but this
> is the question: Why is this behaviour useful? As I see it, it's bad
> practice to give a method and a local variable the same name. At least I
> can't think of an example where it would make sense. Why not simply
> disallow this or at least have the interpreter issue a warning?

Perhaps we could ask about this from the opposite perspective. Would
it not be useful to define local methods --in method scope?

def foo
def bar; 10; end
bar
end

In effect then, a method is nothing more than a lazy variable having
it's own specific rules of scope. There's really no good reason to
restrict name clash.

T.


Brian Candler

5/26/2007 6:35:00 PM

0

On Sun, May 27, 2007 at 01:00:03AM +0900, Henrik Schmidt wrote:
> Hakusa@gmail.com wrote:
> >If a language stops you from doing something just because it's bad
> >practice, then the language is treating you like an idiot.
>
> Fine, so don't stop be. Warn me that I'm doing something which is
> probably a programmer error 99% of the time. Ruby stops me from all
> sorts of things I can do in Perl. I think that's a good thing, since I'm
> a horrible Perl programmer :)
>
> >What if I
> >wanted to override a function for a little while? I could assign it a
> >new value and use the same methods of a different class!
> >
>
> Then you'll just override it. My question is, why would you want to
> override a method with a variable? I have no problem with overloading a
> method with another method, and neither should the interpreter.

The trouble is:

(1) All objects are descendants of Object, which in turn mixes in Kernel.
Many other objects mix in Enumerable, Comparable and other modules.

This means that a typical object has roughly a googol different methods
already present, and it's very easy to pick a local variable name which
happens to collide with one. Silently ignoring this "just works". Giving an
error would be very annoying; instead of "id = 9" I'd have to change it to
"my_id = 9" or somesuch. In the end I'd prefix all local variables with
my_... which would be worse than using something perlish like "$"

(2) From a very practical perspective, it's extremely difficult for Ruby to
generate these warnings.

The problem is: Ruby is a completely dynamic language, and at parse time you
have no idea what methods an object has. The decision as to 'local variable'
or 'method' is made statically, based on inspection of the code
*before* it's executed, which means before any classes and methods have been
created.

To perform the check you're asking for, Ruby would have to add extra
run-time code after *every* local variable access to perform a method search
just to check if a method with the same name exists. Example:

10000.times do
x = flurble()
y = y + x
end

Each time round the loop, the call to flurble() may have ended up defining a
method called 'x' in the current object. So every time round the loop, you'd
have to check, at the point where 'x' was read and/or assigned, that there
was currently no method called 'x' (or 'x=') in the object.

Regards,

Brian.