How much would variable declarations in Ruby make you wince?

  • Thread starter Just Another Victim of the Ambient Morality
  • Start date
J

Just Another Victim of the Ambient Morality

So, I had a conversation with a colleague of mine and he brought up a
feature request for another language that is a lot like Ruby but is not
Ruby. It was an interesting request and, after I had thought about it a
bit, I discovered that I would like this feature, too!

The two most popular sources of bugs for me when programming in Ruby
are:

1) Passing the wrong object as a parameter to a method.
2) Accidentally creating a new variable.

Unfortunately for me, very little can be done about my first point. I
understand and enjoy the power of duck-typing, which specifically allows me
to exercise this bug.
However, something can be done about the second point. Let me exemplify
the problem:


list = create_useful_list

if should_modify_list(list)
# I meant to modify the variable "list" here...
liist = modify_list(list)
end

use_list(list)


...obviously, this is a seriously contrived example but it should
clarify my point. I so amazingly meant to assign to the pre-existing
variable "list" but I accidentally created a new variable. It's not even
typos with me. I often thought I named a variable something descriptive
when I actually named it something else equally descriptive. This can be a
surprisingly annoying bug to track...
A solution to my problem would be to require variable declarations.
Something like the "my" keyword of a strict PERL script. Ruby would
probably not use "my," despite its PERL roots. Maybe "var?"


var list = create_useful_list

if should_modify_list(list)
# A compile time error will occur here...
# ...after 1.9 is released...
liist = modify_list(list)
end

use_list(list)


What do you all think?
Thank you...
 
J

James Britt

Just said:
...obviously, this is a seriously contrived example but it should
clarify my point. I so amazingly meant to assign to the pre-existing
variable "list" but I accidentally created a new variable. It's not even
typos with me. I often thought I named a variable something descriptive
when I actually named it something else equally descriptive. This can be a
surprisingly annoying bug to track...


How are you testing your code?
 
T

Trans

So, I had a conversation with a colleague of mine and he brought up a
feature request for another language that is a lot like Ruby but is not
Ruby. It was an interesting request and, after I had thought about it a
bit, I discovered that I would like this feature, too!

The two most popular sources of bugs for me when programming in Ruby
are:

1) Passing the wrong object as a parameter to a method.

def some_method(a,b,c)
contract_for_some_method(a,b,c) if $DEBUG
...
end

def contract_for_some_method(a,b,c)
raise ArgumentError unless a.is_a?(Foo)
raise ArgumentError unless b.is_a?(Bar)
raise ArgumentError unless c.is_a?(Baz)
# or whatever
end
2) Accidentally creating a new variable.

Unfortunately for me, very little can be done about my first point. I
understand and enjoy the power of duck-typing, which specifically allows me
to exercise this bug.
However, something can be done about the second point. Let me exemplify
the problem:

list = create_useful_list

if should_modify_list(list)
# I meant to modify the variable "list" here...
liist = modify_list(list)
end

use_list(list)

...obviously, this is a seriously contrived example but it should
clarify my point. I so amazingly meant to assign to the pre-existing
variable "list" but I accidentally created a new variable. It's not even
typos with me. I often thought I named a variable something descriptive
when I actually named it something else equally descriptive. This can be a
surprisingly annoying bug to track...
A solution to my problem would be to require variable declarations.
Something like the "my" keyword of a strict PERL script. Ruby would
probably not use "my," despite its PERL roots. Maybe "var?"

var list = create_useful_list

if should_modify_list(list)
# A compile time error will occur here...
# ...after 1.9 is released...
liist = modify_list(list)
end

use_list(list)

What do you all think?
Thank you...

Why do you have troubles like this? How big are your methods? Keep
them small and this, I think, would be very rare.

The most annoying bug I ever have is tracking an errant "end".

T.
 
T

Tim Uckun

A solution to my problem would be to require variable declarations.
Something like the "my" keyword of a strict PERL script. Ruby would
probably not use "my," despite its PERL roots. Maybe "var?"


I think it would be useful especially for people coming to ruby from
non case sensitive languages. I certainly don't see any harm in
setting up something like strict. If you don't want to use it you
don't have to.
 
D

Daniel Berger

I think it would be useful especially for people coming to ruby from
non case sensitive languages. I certainly don't see any harm in
setting up something like strict. If you don't want to use it you
don't have to.

Once you make something like that optional it has a way of becoming
mandatory in a cultural sense. Go ahead, write a Perl program without
strict and try to get Perl community support. You'll be berated (and
probably insulted) within 2 seconds.

No, the solution is to stop writing monolithic top-down scripts where
you can trip yourself up with such a mistake and/or write tests that
would catch something so simple anyway. In all the years I've
programmed in Ruby I have never been bitten by the lack of strict
variable declaration.

Where it *can* be an issue is with instance variables. However, those
are easily smoked out when you run with -w. You *do* run your tests
with warnings on, right. Yes, of course you do. :)

Regards,

Dan

PS - I've suggested to Jim that warnings be turned on by default for
test tasks in Rake.
 
D

Dumaiu

So, I had a conversation with a colleague of mine and he brought up a
feature request for another language that is a lot like Ruby but is not
Ruby. It was an interesting request and, after I had thought about it a
bit, I discovered that I would like this feature, too!

Hum. Why don't you try comp.lang.ruby.like.but.not.ruby instead? I
hear it's "phat."
The two most popular sources of bugs for me when programming in Ruby
are:

1) Passing the wrong object as a parameter to a method.
2) Accidentally creating a new variable.

Seriously, as someone prone to lack of concentration, I agree. A
great many programmers have concluded, probably from painful
experience, that typed variables reduce error. Also I think that
building error-testing into the code will scale better than reliance
only on unit testing.
1). I'm not yet convinced that some kind of sophisticated DBC thing
amenable to duckies can't be created.
2) would be helpful, but it may be a mistake to insist on a keyword.
I think we should concentrate on putting everything that can be into a
DUIIYDLI module ('Don't use it if you don't like it'). Then the
skeptics can't complain.

-Jonathan
 
D

Dumaiu

Once you make something like that optional it has a way of becoming
mandatory in a cultural sense. Go ahead, write a Perl program without
strict and try to get Perl community support. You'll be berated (and
probably insulted) within 2 seconds.

For Perl that may not be a bad thing. And there's a lot loaded into
the words 'something like that.' Safety features? Optional
extensions? Ruby is one big collection of optional "somethings." I
don't think a *lack* of safety features should be culturally
mandatory, either.
No, the solution is to stop writing monolithic top-down scripts where
you can trip yourself up with such a mistake and/or write tests that
would catch something so simple anyway.

This sounds like Trans's objection. But it's a post facto solution.
Relentlessly refactoring and testing during development could fall
into the 'premature optimization' category.
In all the years I've
programmed in Ruby I have never been bitten by the lack of strict
variable declaration.

That's just the thing, some of us get bitten. Please think of the
children.
Where it *can* be an issue is with instance variables.

I have issues with those, too.


Cheerfully yours,

-Jonathan
 
R

Robert Klemme

Hum. Why don't you try comp.lang.ruby.like.but.not.ruby instead? I
hear it's "phat."


Seriously, as someone prone to lack of concentration, I agree. A
great many programmers have concluded, probably from painful
experience, that typed variables reduce error.

Item 2 above was about declared variables, not necessarily typed ones.
Also I think that
building error-testing into the code will scale better than reliance
only on unit testing.
1). I'm not yet convinced that some kind of sophisticated DBC thing
amenable to duckies can't be created.

IMHO DBC and duck typing do not mix very well because DBC takes away the
flexibility which is one of the strengths. Fact is, apparently there
are people who are able to write complex applications in Ruby - even
with more smart automatisms added.
2) would be helpful, but it may be a mistake to insist on a keyword.
I think we should concentrate on putting everything that can be into a
DUIIYDLI module ('Don't use it if you don't like it'). Then the
skeptics can't complain.

That will we hard because you want the missing declaration be caught
during parsing and compiling. If you put this into a module then you
probably need to go back to the source and reparse it which is not
always possible. I don't know how Perl does it but frankly, I do not
really see Perl as the ideal example to model Ruby after.

Bottom line: if you want a safer language with typed and declared
variables use one. This is such a fundamental change to the language
that it does not fit in very well. I also suggest to keep methods
short. This will help improve structure of the code and avoid all sorts
of other bugs as well.

Kind regards

robert
 
J

Jari Williamsson

Just said:
1) Passing the wrong object as a parameter to a method.

Do you mean object or type here? Checking the type is easy if you need to.
2) Accidentally creating a new variable.

Since I started using NetBeans, I would say this is a non-issue now.
That editor is pretty intelligent when it comes to spotting typos in
Ruby code.


Best regards,

Jari Williamsson
 
B

Bill Kelly

From: "Dumaiu said:
This sounds like Trans's objection. But it's a post facto solution.
Relentlessly refactoring and testing during development could fall
into the 'premature optimization' category.

No. Optimizing almost invariably makes code more obscure and more
complex. Thus the reason to do as little optimization as possible,
as late in the project as possible.

The drivers for refactoring are completely opposite from those of
optimization.

The point of refactoring is to improve and simplify the design of
existing code. Refactoring tends to become more difficult the longer
it is put off, and is more risky in the absence of good test
coverage.

As such, it is ideal if refactoring can become a straightforward daily
occurrence; and a comprehensive test suite helps make this possible.
Some kinds of applications are harder to test than others, but it's
almost always worth it to find a way to write automated tests.

In any case, comparing frequent refactoring to premature optimization
is just wrong. . . .


Regards,

Bill
 
D

Dumaiu

Item 2 above was about declared variables, not necessarily typed ones.

Sorry, that was intended as a précis. I probably should have
said 'typed and declared' so it would have applied to both.
IMHO DBC and duck typing do not mix very well because DBC takes away the
flexibility which is one of the strengths. Fact is, apparently there
are people who are able to write complex applications in Ruby - even
with more smart automatisms added.

The paradigms are antipodal, hence the conflict. But I *am not yet
convinced* that there is no acceptable middle ground between the
approach of trying to second-gues absolutely everything--which fights
the language--and the "you know it works because it works, that is,
doesn't blow up" approach. Permit me to think further on this.
That will we hard because you want the missing declaration be caught
during parsing and compiling. If you put this into a module then you
probably need to go back to the source and reparse it which is not
always possible. I don't know how Perl does it but frankly, I do not
really see Perl as the ideal example to model Ruby after.

I don't need compile-time checking and would never ask to jam that
into the language. I was more imagining something modular that would
mimic a lvar. Don't care about Perl.
Bottom line: if you want a safer language with typed and declared
variables use one.

Thanks, but I really like Ruby!

I also suggest to keep methods
short. This will help improve structure of the code and avoid all sorts
of other bugs as well.

Troo. But then you gotta test 'em all, because it's no help if you
have a lot of little methods but don't know which one the bug is in.


Sincerely,

-Jonathan
 
T

Todd Benson

Do you mean object or type here? Checking the type is easy if you need to.

irb(main):001:0> "hello".type
(irb:1): warning: Object#type is deprecated: use Object#class
=> String

You can tell the "type" how exactly? This is a simple example of
semantics, but what's really important for newbies to understand is
that there is no such thing as "type".

This is a danger that will plague any language, IMO.
Since I started using NetBeans, I would say this is a non-issue now.
That editor is pretty intelligent when it comes to spotting typos in
Ruby code.


Best regards,

Jari Williamsson

Todd
 
D

Dumaiu

Do you mean object or type here? Checking the type is easy if you need to.

The problem as I see it is that it's too easy; it comes off as
lazy. The argument for duck typing, valid, is that you should never
really need to. Object#respond_to?() is considered better but not
perfect.
Since I started using NetBeans, I would say this is a non-issue now.
That editor is pretty intelligent when it comes to spotting typos in
Ruby code.

That's an interesting point, the IDE argument. Although I'm
partial to Vim, I guess trying new things is usually a good idea.
Best regards,

Jari Williamsson

You, too.

-Jonathan
 
D

Dumaiu

No. Optimizing almost invariably makes code more obscure and more
complex. Thus the reason to do as little optimization as possible,
as late in the project as possible.

The drivers for refactoring are completely opposite from those of
optimization.

The point of refactoring is to improve and simplify the design of
existing code. Refactoring tends to become more difficult the longer
it is put off, and is more risky in the absence of good test
coverage.

As such, it is ideal if refactoring can become a straightforward daily
occurrence; and a comprehensive test suite helps make this possible.
Some kinds of applications are harder to test than others, but it's
almost always worth it to find a way to write automated tests.

In any case, comparing frequent refactoring to premature optimization
is just wrong. . . .

Regards,

Bill

Perhaps I should avoid buzzwords. I admit that, having never
actually looked 'optimization' up, I may define it more loosely than
you. I didn't mean optimization for performance but for elegance. Ça
ne se dit pas? The purpose of refactoring is to improve code by
increasing elegance, unless I seriously misunderstand. My own
tendency is to overthink it and try to reevaluate a design after every
single change. I think this is another case where balance is best.
If you have achieved such a balance with your "cycles,"
congratulations. I apologize if I offended you.

-Jonathan
 
T

Todd Benson

To be fair, it has to be said that it is less of a problem in
languages that require variables to be declared or typed.

Hmm. Maybe, but I kind of doubt it. var temp is no more or less
succinct than anything else. It doesn't guarantee you "safeness".
Safeness is what databases are for. Pre-declaration is sort of an
empty promise in flow-control.
-Jonathan

Todd
 
D

Dumaiu

Hmm. Maybe, but I kind of doubt it. var temp is no more or less
succinct than anything else. It doesn't guarantee you "safeness".
Safeness is what databases are for. Pre-declaration is sort of an
empty promise in flow-control.

Do you really, truly believe this? I'm going to argue this point.
I'm not saying that predeclaration is innately good: the
disadvantages, whatever they be, might outweigh the advantages. The
only 'promise' I can see it making is that the kind of error that
started this discussion will be less likely. After writing

var list = create_useful_list

writing

liist = modify_list

will report an error. Actually, because it is more succinct. My
reasoning is as follows: if someone thinks declarations are merely
pointless, he might not use them himself but won't object to others
using them. If he objects on principle, it's because he thinks they
clutter the code. Performance aside, declarations are disliked
because they take up space and are annoying to write. They're
annoying to write because it takes extra effort; the extra effort
makes it less likely that it'll happen by accident. It doesn't
'guarantee you "safeness,"' it just guarantees you a little more
safety.

-Jonathan
 
G

Gary Wright

IMHO DBC and duck typing do not mix very well because DBC takes
away the flexibility which is one of the strengths.

This comment caught my eye. I think good contracts are based on
behavior
and not on implementation (as are good tests) and that would seem to
fit right in with duck typing vs. static typing.

Gary Wright
 
M

Marc Heiler

"The most annoying bug I ever have is tracking an errant "end"."

I too often complain about missing end's.
But I was one of those coders that, in PHP, often forgot a ';'

I cant tell you how happy I am with ruby. No more need for ';'

About the missing end's, over time I kinda developed a habit of
knowing where I made an error and can fix it up quickly.
It is not really that problematic for me. HOWEVER, I would actually
not mind some magical per-file way to omit end's based on
indent. :>
 
B

Bill Kelly

From: "Dumaiu said:
Perhaps I should avoid buzzwords. I admit that, having never
actually looked 'optimization' up, I may define it more loosely than
you.

For what it's worth, I'd suggest that the phrase "premature
optimization" may be more akin to canon, than buzzword, and
tends to mean something very specific.

(By canon, I mean, "the body of rules, principles, or standards
accepted as axiomatic and universally binding in a field of study
or art.")

For completeness sake, the original appearance of the phrase in
publication:

"We should forget about small efficiencies, say about 97% of
the time: premature optimization is the root of all evil."

(Knuth, Donald. Structured Programming with go to Statements,
ACM Journal Computing Surveys, Vol 6, No. 4, Dec. 1974. p.268.)
((Knuth is said to have been parahprasing C.A.R. Hoare))

I didn't mean optimization for performance but for elegance. Ça
ne se dit pas? The purpose of refactoring is to improve code by
increasing elegance, unless I seriously misunderstand. My own
tendency is to overthink it and try to reevaluate a design after every
single change. I think this is another case where balance is best.
If you have achieved such a balance with your "cycles,"
congratulations. I apologize if I offended you.

I think I *was* actually offended. <grin> But it was obviously
based on a misunderstanding.

I don't think I've achieved ideal balance yet... I'm usually
coming at it from the other direction: skipping a few refactorings
until I realize some part of the code is really bothering me, then
having to make time for a larger cleanup. But hopefully I'm
improving.


Regards,

Bill
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top