From: 7stud -- Date: 2011-02-25T11:04:07+09:00 Subject: Re: why is $1 in a grep() equal to nil? Eric Christopherson wrote in post #983739: > On Thu, Feb 24, 2011 at 2:59 PM, 7stud -- > wrote: >> end >> ---get_cpu_info--- >> puts "-->#{$1}<---" >> end >> comp1 = Computer.new(1, DataSource.new) >> puts comp1.mouse >> >> >> --output:-- >> Line 32:in `+': can't convert nil into String (TypeError) >> from t.rb:32:in `mouse' >> from t.rb:52 > > I'm not sure of the specifics, but $1 doesn't persist outside of the > block created in the grep statement. When you call comp1.mouse, that's > no longer within that block -- the method was defined in it, but once > it was made a method it took on an existence of its own. $1 is a *global* variable, so saying it doesn't persist outside of a block doesn't make any sense. I think what is happening is that the body of the define_method() call forms a closure around the variable $1. Unfortunately, the problem with global variables is that other parts of the code can change their value. In this instance, I think a subsequent unsuccessful pattern match assigns nil to $1. Here is an example of that: arr = ["hello"] arr.each do |x| x =~ /h(.)ll/ puts $1 end puts $1 "hello" =~ /xxx/ puts $1 --output:-- e e nil There are a lot other methods in the DataSource class that are inherited by all classes, and the last one in the list must not be one of the methods I defined, so the pattern match fails against that method name, and $1 gets set to nil. Subsequently, when I call the mouse() method, it reads the current value of $1, which is nil. Assigning $1 to a local variable, like 'name', means that each method created by define_method() gets its own distinct 'name' variable in the method body. -- Posted via http://www.ruby-forum.com/.