7stud 7stud schrieb:
> (...)
> If I run the following code, I don't get any errors:
> 
> class MegaGreeter
>         attr_accessor :names
> 
>         #constructor
>         def initialize(names = "world")
>                 @names = names
>         end
> 
>         #functions:
>         def say_hi
>                 if @names.nil?
>                         puts "..."
>                 elseif @names.respond_to?("each")
>                         @names.each do |name|
>                                 puts "Hello #{name}!"
>                         end
>                 else
>                         puts "Hello #{@names}!"
>                 end
>         end
> end
> if __FILE__ == $0
>         mg = MegaGreeter.new(["Sally", "Jane", "Bob"])
>         mg.say_hi
> end

Hi 7stud,

when reading (compiling) your code, Ruby can only detect syntactic 
errors, and your code is syntactically correct. Other errors can only be 
determined at run time. Let me show you...

You get an error when you try your code with another instance:

   mg2 = MegaGreeter.new(nil)
   mg2.say_hi

Output:

   ...
   in `say_hi': undefined method `elseif' (NoMethodError)

This error message shows that Ruby tried to execute the method #elseif, 
which obviously isn't defined. Ruby cannot decide in advance whether 
there will be an error or not:

   mg3 = MegaGreeter.new(nil)

   def mg3.elseif(arg)
     puts "Hello from elseif with arg #{arg}"
   end

   mg3.say_hi

This code defines the method #elseif for the object mg3. The output is:

   ...
   Hello from elseif with arg false
   in `say_hi': undefined method `each' for nil:NilClass (NoMethodError)

You can see that the #elseif method is called, but then there's an error 
in the next line: because @names is nil in this case, we call the method 
#each on the object nil, which isn't defined.

I should have said: normally it isn't defined. We can change this:

   def nil.each
     yield "nil"
   end

   mg3.say_hi

This code defines the method #each for the object nil, so that it passes 
the string "nil" to the block. The output is:

   ...
   Hello from elseif with arg true
   Hello nil!

You can see that your code executes fine in this case. This can only be 
determined by actually running the code. Ruby is very dynamic, which 
sometimes isn't an advantage, as has been in your case. But it can be a 
very powerful tool, which is why we all hang out here.

Regards,
Pit