Why does local_variables return local variables that have not been assigned?

Why does local_variables return local variables that have not yet been assigned (assigned after calling local_variables )?

 a = 2 @aa = 1 # a = b # this will raise an error. puts "local: #{ local_variables }" puts "instance: #{ instance_variables }" b = 2 @bb = 2 puts "local: #{ local_variables }" puts "instance: #{ instance_variables }" 

result:

 local: [:a, :b] instance: [:@aa] local: [:a, :b] instance: [:@aa, :@bb] 

I expect behavior like instance_variables , which returns only those variables that were already assigned at that moment.

+4
source share
2 answers

Kernel#local_variables lists all local variables that are in the current scope, including those that have not yet been assigned a value. MRI parses the locals variables in each area and declares them before the code itself is executed (e.g. puts local_variables.inspect ), so they are displayed even when local_variables is called before these variables are defined

But note that defined? still returns nil for variables that have not yet been assigned when local_variables is called:

 $ cat /tmp/locals #!/usr/bin/env ruby a = 5 puts local_variables.inspect puts defined?(a) puts (defined?(b) || "[undefined]") b = 10 puts defined?(b) def foo c = 15 puts local_variables.inspect d = 20 end foo $ ruby /tmp/locals [:a, :b] local-variable [undefined] local-variable [:c, :d] 
+1
source

Ruby creates local variables at compile time . Instance variables are explicitly bound to the instance and can be easily accessed. However, b may be:

  • Method call
  • self.b
  • local variable b

See Brian Candler's answer (Google cache) . This is also the reason why you cannot create local variables at runtime with eval.

+1
source

All Articles