0
define_method :hash_count do 
  hash = ''
  hash << 'X' while hash.length < 25
  hash # returns the hash from the method
end

puts hash

I was expecting

XXXXXXXXXXXXXXXXXXXXXXXX

To be outputted to the screen. Instead I get bizarre random numbers such as

3280471151433993928

and

-1945829393073068570

Could someone please explain? Scoping in Ruby seems way weirder than in PHP/Javascript!

4

2 回答 2

1

Hello again :) Try this:

def hash_count
  hash = ''
  hash << 'X' while hash.length < 25
  hash # returns the hash from the method
end

puts hash_count

You have called hash, which is the same as self.hash. See the documentation for details about the hash method. Note: hash outside of the method is not the same as hash (the string) within your method, because hash (the string) is defined in the method scope.

Note: You may still use define_method :hash_count do, but from the code I've seen here, a simple def hash_count is more readable.

于 2013-05-02T14:14:43.190 回答
1

I see what you expect this. It is a scope problem.

The variable hash already exists both inside and outside of the block as a function call. Whenever you declare a variable or function with the same name you will be shadowing it in that scope - that is, make the older invalid and using your just defined behaviour for that name.

In your case, you declared it in the scope of your block, and so shadowed the Object#hash function as a string variable inside the do/end block. However, the variable was not shadowed outside of your block, and thus kept the original function call.

So, for example

hash = ''
define_method :hash_count do 
  hash << 'X' while hash.length < 25
  hash # returns the hash from the method
end

puts hash

Should work as you expected because you are shadowing the hash in the same scope your are using puts. For similar reasons, if you do

def hash_count
  a = ''
  a << 'X' while hash.length < 25
  a # returns the hash from the method
end

puts a

it should raise an undefined variable error, because it is not defined in this scope.

于 2013-05-02T15:12:52.280 回答