Skip to content

Instantly share code, notes, and snippets.

@khoan
Created August 22, 2012 15:06
Show Gist options
  • Save khoan/3426553 to your computer and use it in GitHub Desktop.
Save khoan/3426553 to your computer and use it in GitHub Desktop.
ruby defined? operator

Run this on ruby 1.9

require 'delegate'

class Bam < SimpleDelegator
  def bam
    defined? Bam
  end

  def rails
    defined? Rails
  end
end

module Rails; end

bam = Bam.new(Object.new)

# I'm expecting "constant" to be returned but it's something else in fact.
# Can defined? operator be used inside SimpleDelegator?
bam.bam
# => nil
bam.rails
# => nil

# wtf moment
defined? Bam
# => "constant"
defined? Rails
# => "constant"

Something is up inside SimpleDelegator...

class Normal
  def bam
    defined? Normal
  end
end

Normal.new.bam
# => "constant"

# Mon_Ouie: Module#const_defined?
# Mon_Ouie: You can also just explicitly start from top-level using ::SomeConstant
#
# Ok, let's try that again...

class Bam < SimpleDelegator
  def bam
    defined? ::Bam
  end

  def rails
    Module.const_defined? :Rails
  end
end

bam = Bam.new(Object.new)

bam.bam
# => "constant"

bam.rails
# => true

# hectic, turns out BasicObject is outside of the namespace of the standard library
# see http://www.ruby-doc.org/core-1.9.3/BasicObject.html
@khoan
Copy link
Author

khoan commented Aug 22, 2012

IRC freenode

[01:14am] judofyr: khoa: defined? will only return "constant" if there's literally a constant right after it
[01:14am] judofyr: defined?(foo) will either return "local-variable", "method" or nil
[01:14am] judofyr: no matter what
[01:14am] judofyr: because it looks at it at parse-time figures "this can either be a lvar or a method name"
[01:14am] m3nd3s left the chat room. (Remote host closed the connection)
[01:14am] judofyr: then the actual definedness-check is done at runtime
[01:14am] rolfb left the chat room. (Quit: Linkinus - http://linkinus.com)
[01:15am] hynkle joined the chat room.
[01:15am] judofyr: it's rather magic
[01:16am] m3nd3s_ joined the chat room.
[01:17am] whitequark: yeah
[01:17am] whitequark: foo() is NODE_CALL, and "foo" is NODE_VCALL

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