How global are global variables in ruby?
Here's a ruby script:
discarded_rows=-1
def foobar(line)
if line.match('records discarded: *(\d+)') then
discarded_rows=$1;
puts('yepp, I have found: ' + discarded_rows);
end;
end
foobar('records successful: 99 ');
foobar('records discarded: 2 ');
foobar('records unknown: 8 ');
if discarded_rows != 2 then
puts("discarded_rows: #{discarded_rows}");
end
And here's what I believe it does: it declares a (global) variable with the name discarded_rows
. It then declares a function foobar
that checks if the passed argument line
matches "records discarded *\d". If it does, it assignes the number of discarded records to the (what I think is a global) variable discarded_rows
. If it matches, it also prints "yepp...." just to make sure
that the match works.
Th开发者_高级运维e function is called, with one string that should match.
If discarded_rows
is not equal to 2, it prints the according value.
And here's the script's output:
yepp, I have found: 2
discarded_rows: -1
So, clearly, the match worked, and obviously, discarded_rows
is not truly global. Is this correct or do I overlook something?
discarded_rows
is not a global variable. $discarded_rows
would be a global variable.
Zabba is absolutely correct. To elaborate a little bit however, discarded_rows
is a local variable. Code at the top level is treated roughly as though the whole file was being executed as a method. Defining a new method actually happens much more so at runtime than in most languages, to the point where you can write something like
s = gets
if s =~ /(\d+)/
i = $1.to_i
if i < 5
def less_than_five
true
end
else
def less_than_five
false
end
end
else
def less_than_five
raise "not a number"
end
end
p less_than_five
The body of an def end
block introduces a new lexical scope that does not close over the enclosing lexical scope (locals in the surrounding code are not available to the body of the method).
精彩评论