Ruby doesn't seem to check for class names, function names, and so
forth until it actually hits a line that tries to use such a thing. Is
there a way to get it to check up front, without having to run the
script through every possible line of code?
I understand that this is not strictly "syntax" checking, and that Ruby
does actually do a "syntax" check. So I mean some other term, more
along the lines of what a traditional compiler will do (minus the
actual compilation).
That is actually impossible, as the system can not determine which
functions exists at any given line without executing the previous
lines. E.g.
def method_missing(name, *args, &block)
return name if args.length == 0
super(name, *args, &block)
end
foo()
bar(foo())
cheers,
Brian
···
On 07/12/05, William E. Rubin <williamerubin@dodgeit.com> wrote:
Ruby doesn't seem to check for class names, function names, and so
forth until it actually hits a line that tries to use such a thing. Is
there a way to get it to check up front, without having to run the
script through every possible line of code?
I understand that this is not strictly "syntax" checking, and that Ruby
does actually do a "syntax" check. So I mean some other term, more
along the lines of what a traditional compiler will do (minus the
actual compilation).
On 12/7/05, William E. Rubin <williamerubin@dodgeit.com> wrote:
Ruby doesn't seem to check for class names, function names, and so
forth until it actually hits a line that tries to use such a thing. Is
there a way to get it to check up front, without having to run the
script through every possible line of code?
I understand that this is not strictly "syntax" checking, and that Ruby
does actually do a "syntax" check. So I mean some other term, more
along the lines of what a traditional compiler will do (minus the
actual compilation).
Ruby doesn't seem to check for class names, function names, and so
forth until it actually hits a line that tries to use such a thing. Is
there a way to get it to check up front, without having to run the
script through every possible line of code?
I understand that this is not strictly "syntax" checking, and that Ruby
does actually do a "syntax" check. So I mean some other term, more
along the lines of what a traditional compiler will do (minus the
actual compilation).
Hi William,
if you call the ruby interpreter with the -c command line option, then it performs a syntax check:
On the other hand, if you want to syntactically check for valid class names, then you're out of luck. Ruby is too dynamic. Look at this little script:
C:\tmp>type r.rb
print "enter class name: "
name = gets.chomp
Object.const_set name, Class.new
p X.new
This script prompts the user for a classname and then creates a new class under that name. It then tries to create an instance of class X. You can't check whether "X" is a valid class name without actually running the code:
C:\tmp>ruby r.rb
enter class name: X
#<X:0x2b31708>
C:\tmp>ruby r.rb
enter class name: Y
C:/tmp/r.rb:5: uninitialized constant X (NameError)
I'm not sure the Ruby IDEs can give you more hints about misspelled names. The best way for me is simply doing Test Driven Development.
Thanks for the explanation. But there certainly could at least be a
way to produce warnings. In your example, it could warn (without
having executed any of your code) that X might be uninitialized.
I'm not saying Ruby should do this as a default, but it would be nice
to have an option (or a separate tool) to do so.
I mean, I just had a Ruby script crash because one line of code
contained "RegExp" instead of "Regexp". This script had been working
fine for quite some time, but it just happened to get into the
situation where that line was encountered for the first time. It would
have been nice to have had a tool that told me "Warning: RegExp might
not exist".
That's the exact scenario that unit tests are great for, finding issues in
parts of code that aren't hit often, or nearly at all. If they're covered
by a unit test though you know, right away that something is wrong, and you
can fix it, without waiting for that scenario to arrive.
···
On 12/7/05, William E. Rubin <williamerubin@dodgeit.com> wrote:
Thanks for the explanation. But there certainly could at least be a
way to produce warnings. In your example, it could warn (without
having executed any of your code) that X might be uninitialized.
I'm not saying Ruby should do this as a default, but it would be nice
to have an option (or a separate tool) to do so.
I mean, I just had a Ruby script crash because one line of code
contained "RegExp" instead of "Regexp". This script had been working
fine for quite some time, but it just happened to get into the
situation where that line was encountered for the first time. It would
have been nice to have had a tool that told me "Warning: RegExp might
not exist".
--
===Tanner Burson===
tanner.burson@gmail.com http://tannerburson.com <---Might even work one day...
At the risk of sounding pedantic, Test Driven Development really is the best solution to this. Not only will it catch the cases you are talking about, but if done right it can even catch the dynamic cases that were given as counterexamples earlier. If you have tests that cover your code sufficiently, you'll find these kinds of problems much, much sooner. And Ruby makes TDD so easy it's almost criminal to not take advantage of it.
- Jamis
···
On Dec 7, 2005, at 10:32 AM, William E. Rubin wrote:
Thanks for the explanation. But there certainly could at least be a
way to produce warnings. In your example, it could warn (without
having executed any of your code) that X might be uninitialized.
I'm not saying Ruby should do this as a default, but it would be nice
to have an option (or a separate tool) to do so.
I mean, I just had a Ruby script crash because one line of code
contained "RegExp" instead of "Regexp". This script had been working
fine for quite some time, but it just happened to get into the
situation where that line was encountered for the first time. It would
have been nice to have had a tool that told me "Warning: RegExp might
not exist".
At that particular line, is FileUtils loaded, or not?
···
On Wed, 07 Dec 2005 17:30:17 -0000, William E. Rubin <williamerubin@dodgeit.com> wrote:
Thanks for the explanation. But there certainly could at least be a
way to produce warnings. In your example, it could warn (without
having executed any of your code) that X might be uninitialized.
I'm not saying Ruby should do this as a default, but it would be nice
to have an option (or a separate tool) to do so.
I mean, I just had a Ruby script crash because one line of code
contained "RegExp" instead of "Regexp". This script had been working
fine for quite some time, but it just happened to get into the
situation where that line was encountered for the first time. It would
have been nice to have had a tool that told me "Warning: RegExp might
not exist".
--
Ross Bamford - rosco@roscopeco.remove.co.uk
"\e[1;31mL"
That's the exact scenario that unit tests are great for, finding issues in
parts of code that aren't hit often, or nearly at all. If they're covered
by a unit test though you know, right away that something is wrong, and you
can fix it, without waiting for that scenario to arrive.
Well sure, but for a quick and dirty one-off script, that you're
potentially changing a bunch as the need arises, it's not always
feasible (timewise) to design unit tests for every possible scenario,
nor to keep them up to date.
At the risk of sounding pedantic, Test Driven Development really is
the best solution to this. Not only will it catch the cases you are
talking about, but if done right it can even catch the dynamic cases
that were given as counterexamples earlier. If you have tests that
cover your code sufficiently, you'll find these kinds of problems
much, much sooner. And Ruby makes TDD so easy it's almost criminal to
not take advantage of it.
At the risk of repeating myself, it seems to me that for one-off
scripts that you may constantly be tweaking as the need arises, the
time cost of designing unit tests, and keeping them up to date, for
every possible scenario, is prohibitive.
That said, I notice that you have capitalized "Test Driven
Development"; that and the fact that you say that Ruby makes it so easy
that it's criminal to not take advantage of it leads me to believe that
you might be talking about something very specific, perhaps involving
some specific tool or specific coding technique, that I am not aware
of, as opposed to talking about the generic "unit test your code"
theory.
If so, could you please elaborate? Pointers to a website, or Google
search terms, or whatever, would be appreciated greatly.
At that particular line, is FileUtils loaded, or not?
You're asking it a question - "does FileUtils exist or not" - that it
is not intended to answer, and that it doesn't claim to be able to
answer.
What it can do, however, is tell you that it looks like FileUtils might
not exist. And that would help in a whole lot of cases, no matter how
many pathological counterexamples you can come up with.
I find that Unit Tests cut my debugging time to nearly non-existent and they cause me to plan for change from the get-go. I wonder how much time that gives back... Enough to offset the tests?
James Edward Gray II
···
On Dec 7, 2005, at 12:07 PM, William E. Rubin wrote:
That's the exact scenario that unit tests are great for, finding issues in
parts of code that aren't hit often, or nearly at all. If they're covered
by a unit test though you know, right away that something is wrong, and you
can fix it, without waiting for that scenario to arrive.
Well sure, but for a quick and dirty one-off script, that you're
potentially changing a bunch as the need arises, it's not always
feasible (timewise) to design unit tests for every possible scenario,
nor to keep them up to date.
If so, could you please elaborate? Pointers to a website, or Google
search terms, or whatever, would be appreciated greatly.
Test Driven Design (TDD, aka Test First Developement) are techniques
that drive the design of your code through the writting of tests. The
concepts were popularized by the Extreme Programming crowd, but TDD
transcends that group and is easily applicable development techniques
beyond XP.
That last one is particularly good if you learn by seeing things in
action rather than reading about the technique. TDD is fist introduced
in the Craftsman # 5 (Baby Steps), but you might want to read the others
in the series to get a feel for the characters.
I've been doing TDD for about 5 years now is is easily the single
biggest improvement I've made in my coding technique in the 25 years
I've been writing code.
Well, I don't see how it could really do that, without executing all code up to a certain point. Again, bear in mind that at the same point in that script, FileUtils may or may not be loaded, depending on what's already happened. How about if you had another script using the above:
def suicide
begin
eval File.read('roulette.rb')
rescue
unless FileUtils
require 'fileutils'
retry
end
end
end
Regardless of what the example does, my point is, how should it warn you? When? If it worked just by looking at whether it _may_ be undefined, then surely it'd always warn you in the above situation?
I can see that it would probably help in a lot of cases, but it would be an annoying gripe in a lot of the more complex cases, which is where Ruby shines. It's that dynamicity that attracted me to Ruby, the fact that pretty much everything is executable code, and I think it'd be an enormous shame to start imposing static-language requirements on it so a few people can avoid writing a few testcases ...
Just my opinion...
···
On Thu, 08 Dec 2005 18:52:24 -0000, William E. Rubin <williamerubin@dodgeit.com> wrote:
At that particular line, is FileUtils loaded, or not?
You're asking it a question - "does FileUtils exist or not" - that it
is not intended to answer, and that it doesn't claim to be able to
answer.
What it can do, however, is tell you that it looks like FileUtils might
not exist. And that would help in a whole lot of cases, no matter how
many pathological counterexamples you can come up with.
--
Ross Bamford - rosco@roscopeco.remove.co.uk
"\e[1;31mL"
That last one is particularly good if you learn by seeing things in
action rather than reading about the technique.
("That last one" being the "Craftsman").
All interesting, and looks useful. The Craftsman one, though, struck
me as absurd. What I got out of that article was this:
(1) The programmer tasked with factoring numbers did not know how to
factor numbers. He did not realize this until he saw his code fail a
particular test case.
(2) He claims that he would have never been able to figure out how to
factor numbers without having seen that test case fail.
(3) Rather than go back and learn how to factor numbers, as he should
have, he instead progressively modifies his code to pass more and more
test cases.
(4) He then goes on to happily assume that his final code is good,
because it passed several test cases.
Regardless of what the example does, my point is, how should it warn you?
By saying "foo might be undefined at line 2351".
When?
When you ask it to. I'm not saying that such warnings should be output
by default.
If it worked just by looking at whether it _may_ be undefined, then
surely it'd always warn you in the above situation?
Assuming that you asked it to, then yes. Or, potentially, there could
be a way to state, within the source code, for the benefit of this new
tool, that "Yeah, I already know that it looks like 'foo' might be
undefined on the next line (or in this function, or in this file).
Don't bother telling me about that".
I can see that it would probably help in a lot of cases
I agree.
but it would be
an annoying gripe in a lot of the more complex cases, which is where Ruby
shines.
Then don't use it in such cases. Or, if you find it useful in some
complex case except for such annoyances, use it, but invoke the "Yeah,
I know" option described above.