Forum: Ruby A major ruby annoyance!

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
79437edc07125851d702c4e8b29f969b?d=identicon&s=25 Talha Oktay (Guest)
on 2006-05-07 01:00
(Received via mailing list)
I am a newbie in Ruby. I have read several books including pickaxe and
wrote
several thousands lines of code. So far, as an ex perl user, I have
found
the major annoyance with ruby is the lack of declaration of variables.
Automatic creation,  in perl jargon autovification is the common feature
of
many high level languages such as perl, paython, visual basic etc. but
most
of the these languages have seen that this not necessarily a good thing
and
created flags, commands to prohibit it if the developer wants to. I
really
wish ruby had one.  Last  several hours  I spent debugging a
malfunctioning
code just to see mistyped variable name was causing all the problem. I
had
to put many log statements which polluted to the code.

I guess in Pickaxe book, unit testing is presented as the cure for this
problem which I do not agree. I can not write a test code for every
peace of
little functionality, besides I am eager to make the compiler or
interpreter
to work for me. Why not tell the interpreter to check the code, instead
of
writing very detailed test programs. I am not a very good typist and I
often
mistype variable names, often I had to depend on vim's auto completion
feature. But I do not want to depend to an editor or an IDE for this.

I have also found the ruby's -w flag does not work as I perl -w flag
does.
In perl warnings are really descriptive.  You can even use a module
called
diagnostics which almost teaches to fix the problem that crashes program
or
generates warning etc. I often do not use -w as because I receive
warnings
from libraries that my code includes or warnings I do not understand at
all.

May be I am the only one who is bothered with these. I do not know.
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-07 01:25
(Received via mailing list)
On May 6, 2006, at 7:00 PM, Talha Oktay wrote:

> thing and
> problem which I do not agree. I can not write a test code for every
> I have also found the ruby's -w flag does not work as I perl -w
> May be I am the only one who is bothered with these. I do not know.
Only instance variables are auto-vivified.

% irb
irb(main):001:0> puts a
NameError: undefined local variable or method `a' for main:Object
         from (irb):1
irb(main):002:0>

I would suggest using the attr_* methods or writing your own
accessors for any case where you might need to access an instance
varible

@something = exp

is probably a bad sign anywhere but initialize and/or

def something=(x)
   ...
end

likewise a = @something should almost always be a = self.something
A6ce942e03edad55d9b504c1e1d859d6?d=identicon&s=25 Jim Freeze (Guest)
on 2006-05-07 06:15
(Received via mailing list)
On May 6, 2006, at 6:00 PM, Talha Oktay wrote:

> I am a newbie in Ruby. I have read several books including pickaxe
> and wrote
> several thousands lines of code. So far, as an ex perl user, I have
> found
> the major annoyance with ruby is the lack of declaration of variables.
> Automatic creation,  in perl jargon autovification is the common
> feature of
> many high level languages such as perl, paython, visual basic etc.
> but most

You can customize autovivification in Ruby. Consider the Hash

h1 = Hash.new { |h,k| h[k] = 0 }
h1[:a]  #=> 0

h2 = Hash.new { |h,k| h[k] = 1 }
h2[:a]  #=> 1

h3 = Hash.new { |h,k| h[k] = [] }
h2[:a]  << "alpha"  #=> ["alpha"]

l = lambda { |h,k| h[k] = Hash.new &l }
h4 = Hash.new &l
h[:a][:b][:c] = 5   #=> { :a => { :b => { :c => {} }}}



> of the these languages have seen that this not necessarily a good
> thing and
> created flags, commands to prohibit it if the developer wants to. I
> really
> wish ruby had one.  Last  several hours  I spent debugging a
> malfunctioning
> code just to see mistyped variable name was causing all the
> problem. I had
> to put many log statements which polluted to the code.

You can try to up the warning level. It might also help to make
smaller methods.
I you want, post your code and let some people take a look to give
you some pointers on how to prevent this type of thing.

> mistype variable names, often I had to depend on vim's auto completion
> feature. But I do not want to depend to an editor or an IDE for this.

The compiler can't think for you. In Ruby, a little bit of code can
do a lot,
in fact, a lot more than a compiler can guess at. Consider:

   [1,2,3].inject(0) { |prod,x| prod * x }
   [1,2,3].inject(1) { |prod,x| prod * x }

How is an interpretive language supposed to know (or take the time to
know)
that the second case is what you want, not the first?

>
> May be I am the only one who is bothered with these. I do not know.

Some mental reprogramming takes time. We can't brain wash you
overnight. ;)

Jim Freeze
A6ce942e03edad55d9b504c1e1d859d6?d=identicon&s=25 Jim Freeze (Guest)
on 2006-05-07 06:51
(Received via mailing list)
Uhm, I need to correct some hasty typos.


> h3 = Hash.new { |h,k| h[k] = [] }
> h2[:a]  << "alpha"  #=> ["alpha"]
should be
> h3[:a]  << "alpha"  #=> ["alpha"]

>
> l = lambda { |h,k| h[k] = Hash.new &l }
> h4 = Hash.new &l
> h[:a][:b][:c] = 5   #=> { :a => { :b => { :c => {} }}}
should be
> h4[:a][:b][:c] = 5   #=> { :a => { :b => { :c => 5 }}}


Jim Freeze
51a34236538906ab994cf9f2e533d14d?d=identicon&s=25 Lou Scoras (ljscoras)
on 2006-05-07 07:37
(Received via mailing list)
I think this is what the OP is getting at.  In ruby:

    hard_to_spell_variable = 43

    puts 'run a few statements'
    puts "maybe output the var #{hard_to_spell_variable}"


    hard_to_speel_variable = 'a new value' # oops...

    print "output the new value."
    puts  "  Should == 'a new value': #{hard_to_spell_variable}" #
doh!!!

Whereas in perl, under the strict pragma, you get:

    my $hard_to_spell_variable = 43

    # ...

    $hard_to_speel_variable = 'a new value' # perl throws a hissy fit.

This does present problems in other places as well.  I've seen it a
couple of times when people are trying to define DSLs.  You want to
force ruby to dispatch to missing_method, but it won't because it
assumes that you are trying to assign to a new local variable

    my_dsl do
      please_dispatch_method = 'some value'
      # undefined local variable!
    end
7010c2a9fa9ebf326c7c858cd656926b?d=identicon&s=25 Frank Hirsch (0ffh)
on 2006-05-07 09:34
Weeellll....

if this does really bother you sooo much
(actally it bothers me a bit as well), you
can anytime trap the object creation process.

Simplest possibility would be to add two
functions to allow/disallow/throw-a-fit/or-
whatever-you-like-best on any attempt to
create an object.

Where is the problem?

Regards, 0ffh
47b36de21d7ecbc824c81d24802a6290?d=identicon&s=25 Minkoo Seo (pool007)
on 2006-05-07 10:38
(Received via mailing list)
In my case, I use -w always, and try to depend on autocompletion feature
available
in vim. (^P, ^N, ^XO)  Other than that, AFAIK, there are no alternatives
in
the language
which doesn't have variable declaration feature.

Thought Ruby has syntax check facility, "ruby -wc", it does not find
typos.
It just check
syntactic errors.

Sincerely,
Minkoo Seo
5d15f83f0e681b138d95f1ec430868fa?d=identicon&s=25 Joey (Guest)
on 2006-05-07 10:44
(Received via mailing list)
Also, how is Ruby meant to know wether something is a typo, or a new
var?

Joey
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-05-07 11:02
(Received via mailing list)
Hi --

On Sun, 7 May 2006, Logan Capaldo wrote:

>
> likewise a = @something should almost always be a = self.something

It all depends.  The attr_* family uses instance variables to do what
it does, but there's no reason that should be viewed as the only or
best or likeliest use of instance variables.  It's layered on top of
a subsystem (instance variables) that have other uses too.


David
7010c2a9fa9ebf326c7c858cd656926b?d=identicon&s=25 Frank Hirsch (0ffh)
on 2006-05-07 13:06
Okay, this should be a start!

>---------------- cut here ----------------<

def local(context,*declared)
  declared=declared.map{|e| e.id2name}
  found=eval("local_variables",context)
  found.each do |name|
    if !declared.include?(name)
      raise "hell"
    end
  end
end

def test
  local binding,:foo,:bar
  foo=0
  bar=0
#  baz=0 # uncomment to raise hell!
end

>---------------- and here ----------------<

Beautify and extend this for a few days,
and you may have something you can live with.


Regards, 0ffh
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-07 20:29
(Received via mailing list)
On May 7, 2006, at 5:00 AM, dblack@wobblini.net wrote:

>> is probably a bad sign anywhere but initialize and/or
> a subsystem (instance variables) that have other uses too.
>
>
> David
>
I wans't suggesting only using ivars for accessors, but I believe
strongly in the uniform access principle. Even if you using ivars for
something completely internal that no one sees, you should still wrap
the accesses to them in methods (private ones).
79437edc07125851d702c4e8b29f969b?d=identicon&s=25 Talha Oktay (Guest)
on 2006-05-08 01:20
(Received via mailing list)
Hi,

Thank you all for the posts. They were all helpful and inspiring. I am
neither live in States(I live in Turkey) nor a native speaker and Louis
J.
Scoras presented my problem beautifully much better than I could. So I
especially thank him for that.

First of all, I would like to say that the problem is valid for all
types of
variables. You can mistype a local variable name in the same block and
you
just create a second variable instantly. You can create an instance
variable
anywhere in the class by adding @ in front of the variable name. If you
mistyped an instance variable name in a method, probably the one you had
properly initialized in your constructor, oops, sorry, you just created
a
new variable and had a brand new bug. If you are agile guy, and spent
double
time writing test for every little functionality, hopefully you would
find
it soon. Nothing protecting us from these kinds of errors. For global
variables, constants they have all the same problem.

What I have understood from all the posts, is that; there is no
syntactical
way for  predeclaration of  variables. All the solutions that you have
provided includes partial solutions to the problem and includes some
kind
of  error handling or conventional code and using them consistently
which I
do not want. According to me, they look ugly in such a consistent
beautiful
language. Besides that kind of custom solutions, according to me, just
increase the complexity of the code.

I would like to comment against posts which simply emphasizes that the
interpreter can not think for us. I know that of course. What if we
could
tell the interpreter by saying that these are the variables that I am
going
to use in the class scope, in a block, in a method or in global scope
etc.
and ask the interpreter not to allow any other variable usage in the
specified scope?  Then the interpreter would definitely know our intent?
I
meant that.

What I liked most about ruby how easy to write classes. While using ruby
I
had to mind shift myself persistently for using object oriented
techniques
in even small scripts. Writing classes, using objects are no longer
burden.
The built in attr_* removes all burden of getters and setters etc. For
example to write a class in perl, java, c++ one has to implement all the
getters or setters. In perl, one can use some custom modules from cpan
which
creates a class for you, but all of which all are non-standard
modules.(Okay
some of the most widely used ones come with the distribution, but they
are
not part of the language) There are many other jewels that ruby has
built-in
or in its standard libraries. Ruby made unconventional, custom
implementations made public and mainstream by making them built-in to
the
language as in attr_* example. On the other hand, for the problem that I
present in my post, I am required to implement custom solutions which
partially solve the problem. The problem that I stated here is one of
the
biggest sources of unintentional bugs. Ruby is supposed to cut down
development time and reduce the unintentional complexity dramatically.
It is
one of most high level languages I have encountered. So I believe ruby
should have not missed this feature. I really hope to see that ruby
language
supports these with a new set of keywords in its next releases.
Otherwise, I
do not think that ruby would be able get of out scripting and the
lightweight web world or get into world big production systems. I
believe
ruby has a capacity to go forward if these kinds of doors could be
closed.

Of course, I talk without understanding the language guts. I know that
variables are just references and everything is dynamically decided etc.
It
may not be easy to implement this. I do not know. But as the
user/customer
of ruby, I find that my development time does not dramatically increased
as
much as I expected. Yes I develop faster, but I lose the time that I
gained
in coding in testing. I prefer testing the functionality and the
requirements not the guts. If I can run the code, I expect that language
issues must be solved. I am very much suprised when I receive a no
method
error. Why do I have to run the statement just to see that object does
not
have that method implemented. I would like to deal with bugs that are
caused
by the misapprehension or misimplementation of the problem. I expect the
compiler, interpreter to handle inconsistencies in the language usage
itself. Ruby currently mixes the problem  domain with the language
domain
because it does not let developer inform itself about language set the
developer wants to use. I do not expect the language to be as strict as
Ada
by default but it should let the developer to configure how strict the
interpreter should be. In perl, a developer can dynamically command the
perl
interpreter how strictly interpret the code. If perl can, whose latest
major
release about 12 years old, ruby has got to do this.

I prefer a language that loudly shouts at with discriptive information
when
I do something wrong instead of running but producing erroneous results.
Just because of this I have the habit of using zillions of assertions in
my
code when I developed in other languages. I have not been able to find
an
assertion module in ruby by the way (yes I know, you do not need it
because
it is very easy to write one or hey, another answer why do I ever need
it..:)). I really admire you all guys because of your self confidence.

Yes, as the Pickaxe books says strict typing made some code less
portable
and less reusable, but I am ready to make that compromise most of the
time
if my name depends on the correct functionality of the software I wrote.

My comments are not to criticize ruby language and its community but to
contribute to it's perfection. I  already feel myself  as rubyist  but
want  this language make its way more broader domain, even better to my
domain..:)

Sincerely.
86e33dee4a89a8879a26487051c216a8?d=identicon&s=25 Michael Fellinger (Guest)
on 2006-05-08 02:03
(Received via mailing list)
You probably should really invest some time into unittesting - it's
worth a lot.
And it is true, i spend at least half of my time on unittests (using
RSpec http://rspec.rubyforge.org/ and RubySelenium
http://rubyselenium.rubyforge.org) but have a solution that works (TM)
and that i can use universally afterwards - always being confident
that it behaves the way i want it to.
I am sorry that I don't have time to answer lengthy on your mail - but
i have to say that wrapping your head around unittesting is worth the
effort and really rewarding in the end.
ah, and controlled declaration of variables would probably kill me :|
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-08 02:54
(Received via mailing list)
And now I shall go off on a tangent, demonstrating the seeds of
methods for "declaring variables" in ruby. It's not complete or
perfect by any means, but I'm sure it can be improved by greater
coders than I. It makes use of Binding.of_caller which for
convenience I have stuck in the actual source file. It also makes use
of an Evil Global Variable?

% cat locals.rb
# File lib/extensions/binding.rb, line 107
def Binding.of_caller(&block)
   old_critical = Thread.critical
   Thread.critical = true
   count = 0
   cc, result, error = Continuation.create(nil, nil)
   error.call if error

   tracer = lambda do |*args|
     type, context = args[0], args[4]
     if type == "return"
       count += 1
       # First this method and then calling one will return --
       # the trace event of the second event gets the context
       # of the method which called the method that called this
       # method.
       if count == 2
	# It would be nice if we could restore the trace_func
	# that was set before we swapped in our own one, but
	# this is impossible without overloading set_trace_func
	# in current Ruby.
	set_trace_func(nil)
	cc.call(eval("binding", context), nil)
       end
     elsif type != "line"
       set_trace_func(nil)
       error_msg = "Binding.of_caller used in non-method context or " +
	"trailing statements of method using it aren't in the block."
       cc.call(nil, lambda { raise(Exception, error_msg ) })
     end
		  end

   unless result
     set_trace_func(tracer)
     return nil
   else
     Thread.critical = old_critical
     yield result
   end
end
# File lib/extensions/continuation.rb, line 61
def Continuation.create(*args, &block)
   cc = nil
   result = callcc { |c|
     cc = c
     block.call(cc) if block and args.empty?
   }
   result ||= args
   return *[cc, *result]
end

def declare_locals(*symbols)
   $__LVARS ||= []
   $__LVARS.concat(symbols)
end

def ensure_locals
   Binding.of_caller do |b|
      lvar_set = eval('local_variables', b)
      undecld_vars = lvar_set - ($__LVARS || [])
      unless undecld_vars.empty?
        warn "Undeclared var(s): #{undecld_vars}"
      end
   end
end

declare_locals 'a', 'b'
a = 1
b = 2
c = 4
puts a + b
ensure_locals

% ruby locals.rb
3
Undeclared var(s): c



Originally I tried to do this with 'set_trace_func' but that doesn't
apparently have an event for setting a variable.
139a2a2f6b330cc59a8dc6384bbf8837?d=identicon&s=25 Corey (Guest)
on 2006-05-08 03:34
How about a programming editor that just looks at the variable names you
have and then compares them with others to see if they are similar, the
editor could even pop up a tool tip that says "Hey are you sure you dont
mean {variable_name}?" I am not really familiar with any editor that
does that i am new to programming and ruby altogether but thats what i
would look for if i was having the same issue.
C1bcb559f87f356698cfad9f6d630235?d=identicon&s=25 Hal Fulton (Guest)
on 2006-05-08 03:46
(Received via mailing list)
Talha Oktay wrote:
> Hi,
>
> Thank you all for the posts. They were all helpful and inspiring. I am
> neither live in States(I live in Turkey) nor a native speaker and Louis J.
> Scoras presented my problem beautifully much better than I could. So I
> especially thank him for that.

[snip]

I am not trying to say your concerns are not valid. But every
newbie comes to Ruby and wants to change it.

My advice is always: Use it for 90 days as it is, and then think
about it some more.

The top things, as I recall, that people insist Ruby absolutely
HAS TO HAVE are:

1. significant whitespace as in Python
2. braces instead of keyword...end
3. static typing
4. variable declarations

But in my opinion Ruby doesn't "have to have" any of these things.
In fact, Ruby evolved from languages that had those things. It
evolved away from them, not toward them.

Humans' evolutionary forebears might feel that gills or a tail or
full-body fur are indispensable. I as a human do not feel a special
need for them.


Hal
Bd0203dc8478deb969d72f52e741bd4f?d=identicon&s=25 Daniel Baird (Guest)
on 2006-05-08 03:58
(Received via mailing list)
On 5/8/06, Corey <0011@hush.com> wrote:
>
> How about a programming editor that just looks at the variable names you
> have and then compares them with others to see if they are similar, the
> editor could even pop up a tool tip that says "Hey are you sure you dont
> mean {variable_name}?" I am not really familiar with any editor that
> does that i am new to programming and ruby altogether but thats what i
> would look for if i was having the same issue.


I saw a Perl module once that caught any exceptions in your running
code,
and decided for itself what you *really* meant.  So if you mis-typed a
variable name, it took a guess at the variable you might have intended
to
use.

That only worked when the code was actually running, so not quite the
same.
It was pretty funny though.. I bet you could knock up a Ruby version in
a
day.

;Daniel

PS I couldn't find it after 90 seconds of searching on CPAN.  Anyone
else
remember this?
A6ce942e03edad55d9b504c1e1d859d6?d=identicon&s=25 Jim Freeze (Guest)
on 2006-05-08 04:19
(Received via mailing list)
Hi

I have a good friend from Turkey.
You've moved farther than him, he still clings to Perl and thinks
$%; help readability. But other than that, you have a lot of
similarities.

He has no time for unit testing. The reason? He's too busy fixing bugs.

On May 7, 2006, at 6:18 PM, Talha Oktay wrote:

> meant that.
One could do this. I'm not sure of the performance hit though. Probably
wouldn't be used by experienced Rubyists.

> much as I expected. Yes I develop faster, but I lose the time that
> I gained
> in coding in testing. I prefer testing the functionality and the
> requirements not the guts.

Are you sure? You need to consider the aggregate of time wasted
by your users and yourself from releasing bugs that could have been
caught from simple unit tests. From my experience, coding without
testing is 4x bad. Programmers can produce twice the code with
twice the bugs instead of 1x the code and 0.01x the bugs.

> If I can run the code, I expect that language
> issues must be solved.

This is not even true with static languages.

> I am very much suprised when I receive a no method
> error. Why do I have to run the statement just to see that object
> does not
> have that method implemented.

Try unit testing for a while and you will see. After doing
   1) write code
   2) write test
   3) run test and see it succeed

you start to get paranoid that your tests aren't being run. :)
Seeing them fail, then succeed has a euphoric effect.

> I would like to deal with bugs that are caused
> by the misapprehension or misimplementation of the problem.

Unit tests help here a lot since you essentially have to state the
problem
from the users perspective.

> I prefer a language that loudly shouts at with discriptive
> information when
> I do something wrong instead of running but producing erroneous
> results.

Dynamic languages typically don't shout. Ruby has much more decorum.

> Just because of this I have the habit of using zillions of
> assertions in my
> code when I developed in other languages. I have not been able to
> find an

Why are you willing to write assertions but not unit tests?


Jim Freeze
E791e5345b9747826e42a1f684920282?d=identicon&s=25 Roy Sutton (Guest)
on 2006-05-08 04:59
(Received via mailing list)
Jim Freeze wrote:
>> specified scope?  Then the interpreter would definitely know our
>> intent? I
>> meant that.
>
> One could do this. I'm not sure of the performance hit though. Probably
> wouldn't be used by experienced Rubyists.
I doubt very much there'd be a performance hit at all for this.
>> I am very much suprised when I receive a no method
>> error. Why do I have to run the statement just to see that object
>> does not
>> have that method implemented.
>
> Try unit testing for a while and you will see. After doing
>   1) write code
>   2) write test
>   3) run test and see it succeed
>
I'm not sure why everyone automatically assumed he did not use unit
testing.  Unit testing certainly can point out there -is- an error.  The
fix he proposes for his problem (typoing variable names) tells him
-where- the problem is.  Unit tests can tell you generally where you
problem is but it still takes the debugging work to step in and find out
what -caused- the problem.  I think people are doing Talha a disservice
by assuming that if he just tested better his problems would go away.

Roy
A6ce942e03edad55d9b504c1e1d859d6?d=identicon&s=25 Jim Freeze (Guest)
on 2006-05-08 05:08
(Received via mailing list)
On May 7, 2006, at 9:56 PM, Roy Sutton wrote:

> I'm not sure why everyone automatically assumed he did not use unit
> testing.  Unit testing certainly can point out there -is- an
> error.  The fix he proposes for his problem (typoing variable
> names) tells him -where- the problem is.  Unit tests can tell you
> generally where you problem is but it still takes the debugging
> work to step in and find out what -caused- the problem.  I think
> people are doing Talha a disservice by assuming that if he just
> tested better his problems would go away.

There have been a couple of good suggestions, but they don't exist
yet. One was an editor
that understood Ruby and could flag new variables. The other was an
addition to the Ruby
parser to point out new variables. Sadly, these don't exist.

I can't remember the last time I had a typo problem with Ruby. Years
ago. And it only lasted
a few seconds. However, I did just have one today with Rails, but
that was with a filename.
(It had the wrong pluralization.) That problem lasted for about 45sec.

If this is Talha's biggest problem, then he's doing better than most
and us mere mortals
can't relate. :)
The reality is I don't see typo's being a big problem for most people
and costing huge chunks
of time on a continuous basis.

Concerning unit testing, Talha may be doing unit testing, but he sure
is complaining
alot about it being non productive. I think most people are saying
that unit testing
is more productive than he realizes, he just needs to give it some time.

Jim Freeze
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-05-08 05:17
(Received via mailing list)
On May 7, 2006, at 9:56 PM, Roy Sutton wrote:

> I'm not sure why everyone automatically assumed he did not use unit
> testing.  Unit testing certainly can point out there -is- an
> error.  The fix he proposes for his problem (typoing variable
> names) tells him -where- the problem is.  Unit tests can tell you
> generally where you problem is but it still takes the debugging
> work to step in and find out what -caused- the problem.

When you get better and better at testing your methods get smaller
and smaller.  That's why we call them "unit" tests.  You just want to
test one small piece of the code, or one unit, at a time.  When you
only have to search three lines of code for a misspelled variable,
you can find it pretty darn quick.

James Edward Gray II
96950c5dec0af04a5c12dae973e96cc7?d=identicon&s=25 Jeremy Tregunna (Guest)
on 2006-05-08 05:50
(Received via mailing list)
> Jim Freeze wrote:
>> Try unit testing for a while and you will see. After doing
>>   1) write code
>>   2) write test
>>   3) run test and see it succeed
>>

Perhaps it's me, but it doesn't make much sense to write your code
BEFORE your test. How do you know that the code is operating right if
you write it before your test?

My suggestion: write your unit tests first, they don't take much
time, so if you find you need to change things a little, having to
rewrite one unit test isn't a big loss.
A6ce942e03edad55d9b504c1e1d859d6?d=identicon&s=25 Jim Freeze (Guest)
on 2006-05-08 06:45
(Received via mailing list)
On May 7, 2006, at 10:48 PM, Jeremy Tregunna wrote:

> if you write it before your test?
Yes. that is what I was trying to point out. Maybe I didn't succeed.
Most people do 1,2,3; 1,2,3; 1,2,3. If they are lucky and no tests
break, then they go back to one of the previous three iterations
and break 1 then run 3, see it fail, and say to themselves, "ok, my
tests are working",  go back, fix 1, and continue on.

It is best to do the following:
   1) write test
   2) run test and see it fail
   3) write code
   4) run test and see it succeed (hopefully) :)


Jim Freeze
4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2006-05-08 07:03
(Received via mailing list)
From: "Roy Sutton" <roys@mindspring.com>
>
> Unit testing certainly can point out there -is- an error.  The
> fix he proposes for his problem (typoing variable names) tells him
> -where- the problem is.  Unit tests can tell you generally where you
> problem is but it still takes the debugging work to step in and find out
> what -caused- the problem.

Hi,

I'm not sure how many people might know about this (or
how many might care <grin>) but: The state of the art in
Test Driven Development has come pretty far.  Drop by a
TDD mailing list and ask folks how many minutes a year
they spend stepping through code anymore; or indeed, if
they even use a debugger at all.

Most TDD folk are likely to say they use a debugger rarely,
if ever.  Maybe to deal with weird interactions with a
third party module to which they don't have tests.  But on
the TDD codebase?  I rarely if ever use a debugger in my C++
TDD code and never in Ruby, nor do I miss it.

Stepping through code in the debugger is inefficient
because it doesn't buy any security for the future.  The
debugger is a great tool when needed--this is definitely
not some anti-debugger rant--but the key difference of
unit tests is that, once written, they are _automated_
tests, where using the debugger is a wholly manual
process each time.

State-of-the-art TDD uses One Button Testing(*) where
you bind a key in your editor to run your tests, and
without interrupting your flow.  You get to keep coding,
while your tests are running, but if the tests don't
pass, you get results that allow you to easily navigate
to the failure point.  If you're running your tests
frequently, chances are the failure relates to code you
just typed moments ago.

(*) Hmm - I see I'm behind the times.  Some folks were
already pushing toward Zero Button Testing three years
ago. :)
http://www.testdriven.com/modules/newbb/viewtopic....

Well anyway: I'd been programming for about 18 years
before I first tried TDD; and I'd gotten damn good at
writing fairly bug-free code in C/C++.  However, I did used
to fear refactoring my bug-free code, for fear of having
to thoroughly manually test it again in the debugger.
In TDD, by contrast, refactoring is an integral part of
the process - with the network of tests catching refactoring
errors the same way it catches other errors while coding.
(Such as the misspellings mentioned in this thread.)

This isn't meant to preach some sort of silver bullet.
But modern TDD is pretty neat.  And it seems like time
much better spent than the stepping-through-code in the
debugger I do on a few regrettably-non-TDD projects.


Regards,

Bill
96950c5dec0af04a5c12dae973e96cc7?d=identicon&s=25 Jeremy Tregunna (Guest)
on 2006-05-08 07:18
(Received via mailing list)
On 8-May-06, at 12:44 AM, Jim Freeze wrote:

>> Perhaps it's me, but it doesn't make much sense to write your code
>> BEFORE your test. How do you know that the code is operating right
>> if you write it before your test?
>
> Yes. that is what I was trying to point out.

Ah, my apologies, I must have deleted your original message since I
only saw this when quoted by someone else... I'm guessing what would
have led me to your intent was clipped.
7010c2a9fa9ebf326c7c858cd656926b?d=identicon&s=25 Frank Hirsch (0ffh)
on 2006-05-08 09:58
Hal Fulton wrote:
> I am not trying to say your concerns are not valid. But every
> newbie comes to Ruby and wants to change it.

Hey, not true! I didn't say a thing! ^_^

> The top things, as I recall, that people insist Ruby absolutely
> HAS TO HAVE are:
> 1. significant whitespace as in Python
> 2. braces instead of keyword...end
> 3. static typing
> 4. variable declarations

Actually, apart from 3, all of those could easily be handled with
a preprocessor. Shouldn't be more than a few days work, I suppose.
But, who the friggin heck would want to break a perfectly beautiful
language like Ruby with STATIC TYPING???

Regards, 0ffh
37ee5fa90f5eaeef62553629382497f7?d=identicon&s=25 Leslie Viljoen (Guest)
on 2006-05-08 14:05
(Received via mailing list)
On 5/8/06, Frank Hirsch <0ffh@frankhirsch.net> wrote:
> language like Ruby with STATIC TYPING???
...and also if you were to add a preprocessor to provide the other
three I wonder if you wouldn't be happier with some other language?
I read over here: http://www.joelonsoftware.com/articles/Wrong.html
the useful rule: "Don't use macros to create your own personal
programming language"

Python would be the place to go if you want significant whitespaces.
C# would be good for the braces and variable declarations.
51a34236538906ab994cf9f2e533d14d?d=identicon&s=25 Lou Scoras (ljscoras)
on 2006-05-08 15:54
(Received via mailing list)
It may also be worth noting two additional points:

First, to be fair, the reason that perl has the *my* keyword for
declaring a variable is to make it a lexically scoped variable.  If
you don't declare a variable with *my* and you aren't using the
*strict* pragma, you get a non-lexical global package variable.  Ruby
defaults to lexically scoped variable anyway.

When you want to do some cool magic tricks in perl you need to turn of
strictures to do it.  Ruby make it easy to extend classes and other
advanced things in a safe way.  Perl makes you mess around with its
symbol table.

Second, what perl buys you on one end, bites you in another.  Unless
you jump through a bunch of hoops and use inside-out objects all of
your perl objects will probably be hashed based.  Since hash keys are
strings and aren't checked in the compile stage you can still shoot
yourself in the foot.  It will operate in exactly the same manner in
ruby:

    $self->{'hard_to_speel_instance_variable'}  # !! not caught by
strict !!

And actually, this turns out to be better in ruby because you can set
the hash miss behaivor to whatever you want:

    hash = Hash.new { |k,v| fail 'You mispeeeled a key ;)' }

which will catch half of your errors.


I think it all boils down, as usual, to flexability vs safety.  Ruby
is nice because it lets you do things quickly and it requires less
code.  On the other hand, having a good test suite--as others have
said--becomes all the more important.

If not, you can always write rubylint ;-)
Eeba234182bcbd7faed9ff52e233394d?d=identicon&s=25 Douglas Livingstone (Guest)
on 2006-05-08 16:13
(Received via mailing list)
2006/5/8, Jim Freeze <jimfreeze@gmail.com>:
>
> Try unit testing for a while and you will see. After doing
>    1) write code
>    2) write test
>    3) run test and see it succeed
>
> you start to get paranoid that your tests aren't being run. :)
> Seeing them fail, then succeed has a euphoric effect.
>

That's why with "Test Driven Development", it goes like this:

1) write test
2) write code
3) run test and see it succeed

(Well really it is more like:

1) write test
2) if test_fails
3)  write code
4) else
5)  go back to 1
6) end

but the picture looks nicer: http://www.agiledata.org/essays/tdd.html )

Douglas
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-05-08 22:11
(Received via mailing list)
Hi --

On Mon, 8 May 2006, Logan Capaldo wrote:

>>> @something = exp
>> it does, but there's no reason that should be viewed as the only or
>> best or likeliest use of instance variables.  It's layered on top of
>> a subsystem (instance variables) that have other uses too.
>>
>>
>> David
>>
> I wans't suggesting only using ivars for accessors, but I believe strongly in
> the uniform access principle. Even if you using ivars for something
> completely internal that no one sees, you should still wrap the accesses to
> them in methods (private ones).

But then you are suggesting that they only be used for accessors :-)

I can't help feeling it's a lot of trouble to do this:

   class C
     def initialize
       self.container = []
     end

     private
     attr_writer :container
   end

rather than:

   class C
     def initialize
       @container = []
     end
   end

if you're just using @container as a state variable here and there.

I think the role of the uniform access principle here is open to
question.  As I understand it, that principle states that the outside
user shouldn't be able to tell whether a value is stored or calculated
-- essentially, an attribute vs. the return value of a method call.
But instance variables are neither attributes nor methods; so they're
not really candidates for being evaluated for uniform/non-uniform
access.  And Ruby's attributes *are* methods.  To that extent, Ruby
actually enforces the UA principle; when you do this:

   obj.something

you know that you've called a method.  There's no other possibility,
so there's no opportunity for divergence of the interface.


David
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-08 22:21
(Received via mailing list)
On May 8, 2006, at 4:10 PM, dblack@wobblini.net wrote:

>>>> accessors for any case where you might need to access an
>>> best or likeliest use of instance variables.  It's layered on top of
>
>
> user shouldn't be able to tell whether a value is stored or calculated
>
>
> David
>
> --
> David A. Black (dblack@wobblini.net)
> * Ruby Power and Light, LLC (http://www.rubypowerandlight.com)
>   > Ruby and Rails consultancy and training
> * Author of "Ruby for Rails" from Manning Publications!
>   > Paper version coming in early May! http://rubyurl.com/DDZ
>


Well at least if you do it my way, you don't get tripped up by typos, ;)
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-05-08 22:40
(Received via mailing list)
On May 6, 2006, at 4:00 PM, Talha Oktay wrote:

Allow me to rearrange your statements a bit.

> thing and
> to work for me.
Yes, you can.  I do.

> Last  several hours  I spent debugging a malfunctioning code just
> to see mistyped variable name was causing all the problem. I had to
> put many log statements which polluted to the code.

Or, you could have written some tests that wouldn't have polluted
your code and saved yourself several hours (and having to pull out
all those log statements).

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-05-08 22:43
(Received via mailing list)
On May 7, 2006, at 4:18 PM, Talha Oktay wrote:

> If you mistyped an instance variable name in a method, probably the
> one you had properly initialized in your constructor, oops, sorry,
> you just created a new variable and had a brand new bug. If you are
> agile guy, and spent double time writing test for every little
> functionality, hopefully you would find it soon.

Well, either you can be an agile guy and type twice as much or you
can do it your way and spend several hours debugging malfunctioning
code and adding log statements.

I've found its easier to be an agile guy and spend my time doing a
little more typing.

Rather than chasing down the same errors over and over why not write
some tests.  I don't like to repeat my mistakes and a solid test
suite keeps that from happening.

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-05-08 22:50
(Received via mailing list)
On May 7, 2006, at 7:56 PM, Roy Sutton wrote:

> generally where you problem is but it still takes the debugging
> work to step in and find out what -caused- the problem.  I think
> people are doing Talha a disservice by assuming that if he just
> tested better his problems would go away.

My unit tests typically tell me which line my errors are on.  You
probably haven't written enough tests for your code or aren't writing
small enough chunks of code.

The biggest change writing tests has done for my coding is to give me
smaller more descriptive methods rather than large methods that do
too much.  A method that is more than 10 lines long is probably
wrong.  A method that is more than 25 is most definitely wrong.

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-05-08 22:53
(Received via mailing list)
On May 7, 2006, at 10:01 PM, Bill Kelly wrote:

> the TDD codebase?  I rarely if ever use a debugger in my C++
> TDD code and never in Ruby, nor do I miss it.
>
> Stepping through code in the debugger is inefficient
> because it doesn't buy any security for the future.  The
> debugger is a great tool when needed--this is definitely
> not some anti-debugger rant--but the key difference of
> unit tests is that, once written, they are _automated_
> tests, where using the debugger is a wholly manual
> process each time.

Not to mention that using a debugger to find bugs is a case of you
repeating yourself.  Writing tests keeps your from duplicating work
that should be automatic.

> already pushing toward Zero Button Testing three years
> ago. :)
> http://www.testdriven.com/modules/newbb/viewtopic.php?
> topic_id=412&forum=6

autotest in ZenTest gives you Zero Button Testing (well, you have to
save the file, does that count?)

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
51a34236538906ab994cf9f2e533d14d?d=identicon&s=25 Lou Scoras (ljscoras)
on 2006-05-08 23:17
(Received via mailing list)
On 5/8/06, Eric Hodel <drbrain@segment7.net> wrote:
> repeating yourself.  Writing tests keeps your from duplicating work
> that should be automatic.

Also not to mention that debuggers modify your code, thus potentially
opening up an entire new can of worms [1]

[1] http://en.wikipedia.org/wiki/Schroedinbug
5a837592409354297424994e8d62f722?d=identicon&s=25 Ryan Davis (Guest)
on 2006-05-08 23:43
(Received via mailing list)
On May 8, 2006, at 1:51 PM, Eric Hodel wrote:

> to save the file, does that count?)
I've also taken it a step further by integrating autotest into emacs.
It allows you to run autotest in the background and click on errors
to go right to the issue. Works pretty well. I'll be releasing it in
the next ZenTest release.
4b174722d1b1a4bbd9672e1ab50c30a9?d=identicon&s=25 Ryan Leavengood (Guest)
on 2006-05-09 00:26
(Received via mailing list)
On 5/8/06, Ryan Davis <ryand-ruby@zenspider.com> wrote:
>
> I've also taken it a step further by integrating autotest into emacs.
> It allows you to run autotest in the background and click on errors
> to go right to the issue. Works pretty well. I'll be releasing it in
> the next ZenTest release.

What about us Vim users? :(

I guess we'll have to hack it up ourselves...

Ryan
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-05-09 00:50
(Received via mailing list)
On Tue, 9 May 2006, Ryan Leavengood wrote:

>
> Ryan

i think the point is that vim users don't make mistakes and therfore
don't
need it (ducks) ;-)

-a
12271b6df73fe29930d65586be5a4a70?d=identicon&s=25 Dave Howell (Guest)
on 2006-05-09 13:48
(Received via mailing list)
On May 7, 2006, at 16:18, Talha Oktay wrote:

> First of all, I would like to say that the problem is valid for all
> types of
> variables. You can mistype a local variable name in the same block and
> you
> just create a second variable instantly.

Not necessarily. You have to mistype a local variable name IN AN
ASSIGNMENT.

I loved Pascal's requirement of pre-declaring variables. It seemed a
very sensible practice to me, and forced other people's code to be more
readable to me, as well as making my own current code more readable to
my future self.

"So why," I asked myself, "haven't I had more problems with variable
name typos in Ruby?"

In point of fact, I *do* have a lot of problems with getting the name
wrong, especially since Ruby, like most primitive computer systems but
unlike the standard behavior of people, thinks that an "A" is
fundamentally different than an "a". That one causes me constant
irritation.

But it's easy to spot and fix, because the error message is almost
always "NIL doesn't have a .whatever method." And lo and behold, it's
because I got my variable name wrong.

I think, Talha, that it's not "Unit testing" that would alleviate your
problems. I think that what would help the most is if you used fewer
variables in the first place. One of my favorite 'tricks' in Ruby is
being able to stack method calls up. In the process of doing that, I
eliminate the need for a lot of intermediate variables.

> increase the complexity of the code.
But *any* means of adding declarations is going to be a "custom
solution." I mean, there's absolutely no way that variable declaration
would become a required component of Ruby. At best, it would be an
option. So if somebody wants to use it, first they have to enable it,
probably by including the module that causes it to be possible. Then
each module or class that wants to enforce it has to mix it in, because
all the existing Ruby code would immediately break if it's required
globally. Then there are the new declarations themselves.

How did you imagine this could be added to Ruby without doing something
"ugly?"

> On the other hand, for the problem that I
> present in my post, I am required to implement custom solutions which
> partially solve the problem. The problem that I stated here is one of
> the
> biggest sources of unintentional bugs. Ruby is supposed to cut down
> development time and reduce the unintentional complexity dramatically.
> It is
> one of most high level languages I have encountered. So I believe ruby
> should have not missed this feature.

I'm not sure you'd get consensus that variable declaration is a
feature. :)

> I prefer a language that loudly shouts at with discriptive information
> when
> I do something wrong instead of running but producing erroneous
> results.

Probably the #1 reason why, having tried using C, I have no intention
of ever exposing myself to such a poorly designed language again.

> I really hope to see that ruby language
> supports these with a new set of keywords in its next releases.

What kind of keywords would you want, and how would they work?
Cf985658ff32a83d07cdfaa22c294fe4?d=identicon&s=25 Edgardo Hames (Guest)
on 2006-05-09 14:33
(Received via mailing list)
On 5/9/06, Dave Howell <groups@grandfenwick.net> wrote:
>
> In point of fact, I *do* have a lot of problems with getting the name
> wrong, especially since Ruby, like most primitive computer systems but
> unlike the standard behavior of people, thinks that an "A" is
> fundamentally different than an "a". That one causes me constant
> irritation.

An 'a' is certainly different from 'A', would you write "alex" or
"Alex", "australian" or "Australian", "april" or "April"?

In Ruby, the naming convention states that you should use CamelCase
for classes and snake_case for method or variables, why would you then
confuse when to use an "a" or and "A"?

Kind regards,
Ed
--
Encontrá a "Tu psicópata favorito" http://tuxmaniac.blogspot.com

Thou shalt study thy libraries and strive not to reinvent them without
cause,
that thy code may be short and readable and thy days pleasant and
productive.
-- Seventh commandment for C programmers
3bb23e7770680ea44a2d79e6d10daaed?d=identicon&s=25 M. Edward (Ed) Borasky (Guest)
on 2006-05-09 15:14
(Received via mailing list)
Edgardo Hames wrote:
> In Ruby, the naming convention states that you should use CamelCase
> for classes and snake_case for method or variables, why would you then
> confuse when to use an "a" or and "A"?
1. Is that a Ruby naming convention or a Rails naming convention?
2. If CamelCase comes from Perl and snake_case comes from Python, what
do you call this convention: makeNextRecord?
3. Should the Ruby conventions be called PickaxeCase? gem_case?

<ducking>

Yes ... I'm bored ... I should be programming ... back to it now?

--
M. Edward (Ed) Borasky

http://linuxcapacityplanning.com
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-05-09 15:24
(Received via mailing list)
On May 9, 2006, at 8:14 AM, M. Edward (Ed) Borasky wrote:

> Edgardo Hames wrote:
>> In Ruby, the naming convention states that you should use CamelCase
>> for classes and snake_case for method or variables, why would you
>> then
>> confuse when to use an "a" or and "A"?
> 1. Is that a Ruby naming convention or a Rails naming convention?

Ruby and even partially encouraged by the interpreter, since
constants are expected to begin with a capital letter.

James Edward Gray II
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-05-09 18:23
(Received via mailing list)
Hi --

On Tue, 9 May 2006, Logan Capaldo wrote:

>>    private
>>
>>
>>  obj.something
>>
>> you know that you've called a method.  There's no other possibility,
>> so there's no opportunity for divergence of the interface.
>
> Well at least if you do it my way, you don't get tripped up by typos, ;)

Why not? :-)

   class C
     def initialize
       self.contanier = []
     end

     private
     attr_writer :container
   end

That will blow up just as much as:

   class C
     def initialize
       @contanier = []
     end

     def insert(x)
       @container << x
     end
   end

(It will happen at a slightly different point, of course.)


David
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-05-09 18:36
(Received via mailing list)
On May 9, 2006, at 12:21 PM, dblack@wobblini.net wrote:

>>>    def initialize
>>>      @container = []
>>> they're
>
>
>   end
>
> (It will happen at a slightly different point, of course.)
>
>
> David
>
Ok, there's _less_ typo trip-ups.
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2006-05-10 15:17
(Received via mailing list)
<soapbox>
Here's *my* major Ruby annoyance: all the time people that are new to
Ruby come up with suggestions / requests in which way Ruby must /
should be changed to be better / the ultimate language / more complete
than C++ / cooler than Perl - apparently without bothering to learn
and use the language for some time and gaining some experience.  These
suggestions are typically based on personal habit and theorization -
both not really suited to yield usability improvements for a larger
audience.
</soapbox>

Cheers

robert
550aa2f280a0dddb317912ed9fa32381?d=identicon&s=25 Daryl Richter (Guest)
on 2006-05-11 18:10
(Received via mailing list)
On May 9, 2006, at 9:14 AM, M. Edward (Ed) Borasky wrote:

>
>
> Edgardo Hames wrote:
>> In Ruby, the naming convention states that you should use CamelCase
>> for classes and snake_case for method or variables, why would you
>> then
>> confuse when to use an "a" or and "A"?
> 1. Is that a Ruby naming convention or a Rails naming convention?
> 2. If CamelCase comes from Perl and snake_case comes from Python, what
> do you call this convention: makeNextRecord?

that's smalltalkMethodCase:  ;)

>
>

--
Daryl

"Stress rarely has a positive impact on our ability to think.
Never, I'd guess."

-- Ron Jeffries, 2005
E791e5345b9747826e42a1f684920282?d=identicon&s=25 Roy Sutton (Guest)
on 2006-05-12 05:52
(Received via mailing list)
Eric Hodel wrote:
>> The fix he proposes for his problem (typoing variable names) tells
> The biggest change writing tests has done for my coding is to give me
> smaller more descriptive methods rather than large methods that do too
> much.  A method that is more than 10 lines long is probably wrong.  A
> method that is more than 25 is most definitely wrong.
>
Just to clarify:  I was playing devils advocate for Talha.  I do write
unit tests and have for many years.  I don't typo variable names
(often).  It's a non-issue for me.  I was merely trying to re-express
his idea for him.

Roy
This topic is locked and can not be replied to.