From: Brian Candler Date: 2010-11-11T23:49:59+09:00 Subject: Re: Analyzer for errors in code ? David Unric wrote in post #960444: > My appologies I did not realized sooner the deeper conceptual > differencies between these languages. > Despite of that, if Ruby cann't decide if mymsg is a variable or a > method call in advance, how does it rule out the possibility for a > static parser to notify the 'mymsg' symbol has no assignment or method > definiton in the source code ? On the contrary: ruby *does* always decide (statically, at parse time, not at run-time) whether a bareword is a local variable or a method call, based on whether a previous assignment statement exists previously in the same scope. e.g. def foo if false x = 123 end puts x # prints nil - x is a local variable puts y # NameError puts z() # NoMethodError end foo Although the assignment to x was never executed, it exists in the parse tree before the point where it is referenced. Therefore at that point bareword x is known to be a local variable. At runtime the value is nil because no assignment was actually executed. y is decided statically to be a method call, as the parsetree shows, because no assignment was seen. Note however that the error message says "undefined local variable or method `y'". The programmer might have meant to assign to a local variable called y, or might have meant to define a method called y. Neither was done, but Ruby has no way to tell which you intended. z() is known from the syntax definitely to be a method call, and so the error is "undefined method `z'". The same would be true for self.z. It doesn't matter whether a statement z=... exists earlier. Unfortunately, because Ruby doesn't require you to annotate your code, there is no additional information which could be used to highlight an anomaly. For example, in perl, scalar variables are flagged by $. If you do $myarg = 123; ... print $my_arg; it can see that $my_arg is used only once, and is therefore likely an error. With 'use strict' you are forced to declare your variables, so every variable must have a matching declaration. The non-verbose nature of Ruby, combined with the dynamic definition of methods at runtime means that these tests simply can't be done. Dynamic method definitions are very widely used - look at code which uses ActiveRecord for instance. The methods in an object are based on the columns in the database which the program connects to. And what this means is, you need tests. Your test suite needs to execute each line of code in your source at least once. A code coverage tool like 'rcov' can help you achieve that, or if you are paranoid look at 'heckle'. Is this harder or more expensive than static code checking? Only if you take the point of view that you don't need unit tests. -- Posted via http://www.ruby-forum.com/.