Skip to content

Instantly share code, notes, and snippets.

@chriseppstein
Created May 29, 2014 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chriseppstein/3eecf49d51155b5ccdc9 to your computer and use it in GitHub Desktop.
Save chriseppstein/3eecf49d51155b5ccdc9 to your computer and use it in GitHub Desktop.
foo = 1 unless defined?(foo)
foo #=> nil
FOO = 1 unless defined?(FOO)
FOO # => 1
@miah
Copy link

miah commented May 29, 2014

[5] pry(main)> FOO = 'bar'
=> "bar"
[6] pry(main)> FOO = 1 unless defined?(FOO)
=> nil
[7] pry(main)> FOO
=> "bar"

@chriseppstein
Copy link
Author

Right, they both behave the same if already defined. My WTF is about how they behave differently when not already defined.

@brixen
Copy link

brixen commented May 29, 2014

Merely mentioning a local variable defines it in that scope, even if that code would never execute.

if false
  a = 1
end

p defined?(a)
$ ruby -v local.rb
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]
"local-variable"

@headius
Copy link

headius commented May 29, 2014

@chriseppstein Yeah, I can see how this would be confusing. Local variables are considered "defined" but not yet assigned once they're first encountered in source, since that's the point at which storage must be available for them in local scope. Constants are not considered defined until actually assigned, since that's the point at which we actually need storage for them.

I don't think it's inconsistent, since constants are essentially stored in global state, while local variables are only stored in per-call state. Constants "can't" (shouldn't) be reassigned. A method's local variables can't be accessed outside that method body (unless shoved into the heap). They're very different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment