VERSION constant issue

Ruby's VERSION constant is getting in the way of using #const_missing
in my module. Here's some example code:

  module Foo
    def self.const_data
      @const_data ||= { 'version' => '1.0.0' }
    end

    def self.const_missing(name)
      key = name.to_s.downcase
      const_data[key] || super(name)
    end
  end

  Foo::VERSION #=> '1.8.7'

How can I fix this?

I tried `remove_const(:VERSION)` at the toplevel but discovered that
some Ruby library don't like that (sorry, can't recall which it was
off hand).

Is this really an issue with ::VERSION? To me this rather looks like
an issue with lookup logic (either the general or yours) since the
same would apply to all other constants, wouldn't it?

Kind regards

robert

···

On Thu, Nov 25, 2010 at 2:54 PM, Intransition <transfire@gmail.com> wrote:

Ruby's VERSION constant is getting in the way of using #const_missing
in my module. Here's some example code:

module Foo
def self.const_data
@const_data ||= { 'version' => '1.0.0' }
end

def self.const_missing(name)
key = name.to_s.downcase
const_data[key] || super(name)
end
end

Foo::VERSION #=> '1.8.7'

How can I fix this?

I tried `remove_const(:VERSION)` at the toplevel but discovered that
some Ruby library don't like that (sorry, can't recall which it was
off hand).

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

hrm...

cfp:~ > cat a.rb
module Lib
  def Lib.const_data
    @const_data ||= {
      'version' => '4.2.0'
    }
  end

  def Lib.const_missing(const)
    const_data[const.to_s.downcase] || super
  end
end

p Lib::VERSION

cfp:~ > rvm a.rb

info: ruby-1.8.7-p302: ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-
darwin9.8.0]

"4.2.0"

info: ruby-1.9.2-p0: ruby 1.9.2p0 (2010-08-18 revision 29036) [i386-
darwin9.8.0]

"4.2.0"

Here are my results.

module Foo
  def self.const_data
    @const_data ||= { 'version' => '1.0.0' }
  end

  def self.const_missing(name)
    key = name.to_s.downcase
    const_data[key] || super(name)
  end

  VERSION # => "1.8.7"
  self::VERSION # => "1.0.0"

  def self.method
    VERSION # => "1.8.7"
  end
  method
end

# going back through ruby versions
# I wasn't able to get these to print
# the ruby version until 1.7.1
# thanks, ruby-versions.net :slight_smile:
Foo::VERSION # => "1.0.0"
Foo::VERSION # => "1.0.0"

···

On Thu, Nov 25, 2010 at 7:54 AM, Intransition <transfire@gmail.com> wrote:

Ruby's VERSION constant is getting in the way of using #const_missing
in my module. Here's some example code:

module Foo
   def self.const_data
     @const_data ||= { 'version' => '1.0.0' }
   end

   def self.const_missing(name)
     key = name.to_s.downcase
     const_data[key] || super(name)
   end
end

Foo::VERSION #=> '1.8.7'

How can I fix this?

I tried `remove_const(:VERSION)` at the toplevel but discovered that
some Ruby library don't like that (sorry, can't recall which it was
off hand).

Ruby's VERSION constant is getting in the way of using #const_missing
in my module. Here's some example code:

module Foo
   def self.const_data
     @const_data ||= { 'version' => '1.0.0' }
   end

   def self.const_missing(name)
     key = name.to_s.downcase
     const_data[key] || super(name)
   end
end

Foo::VERSION #=> '1.8.7'

How can I fix this?

What would ::const_data provide that Module#constants, Module#const_get and Module#const_set and direct constant access don't provide? If it's something legitimate, invert ::const_data to reference real constants via introspection and get rid of const_missing.

I tried `remove_const(:VERSION)` at the toplevel but discovered that
some Ruby library don't like that (sorry, can't recall which it was
off hand).

File a bug, they should be using RUBY_VERSION.

···

On Nov 25, 2010, at 05:54, Intransition wrote:

Hmmm... I haven't been able to quite get the rhyme or reason of the
behavior, but I just got the error again. The code is:

  class TracePoint

    # Access to metadata.
    def self.metadata
      @metadata ||= (
        require 'yaml'
        YAML.load(File.new(File.dirname(__FILE__) + '/
tracepoint.yml'))
      )
    end

    # Access metadata as constants.
    def self.const_missing(name)
      name = name.to_s
      metadata[name] || super(name)
    end

When I use run:

  require 'tracepoint'
  TracePoint::VERSION

I get:

tryit.rb:2: warning: toplevel constant VERSION referenced by
TracePoint::VERSION
"1.8.7"

I got this on both:
  ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux]
  ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux]

Ruby 1.9.2 is not a problem.

···

On Nov 25, 12:54 pm, Josh Cheek <josh.ch...@gmail.com> wrote:

On Thu, Nov 25, 2010 at 7:54 AM, Intransition <transf...@gmail.com> wrote:
> Ruby's VERSION constant is getting in the way of using #const_missing
> in my module. Here's some example code:

> module Foo
> def self.const_data
> @const_data ||= { 'version' => '1.0.0' }
> end

> def self.const_missing(name)
> key = name.to_s.downcase
> const_data[key] || super(name)
> end
> end

> Foo::VERSION #=> '1.8.7'

> How can I fix this?

> I tried `remove_const(:VERSION)` at the toplevel but discovered that
> some Ruby library don't like that (sorry, can't recall which it was
> off hand).

Here are my results.

module Foo
def self.const_data
@const_data ||= { 'version' => '1.0.0' }
end

def self.const_missing(name)
key = name.to_s.downcase
const_data[key] || super(name)
end

VERSION # => "1.8.7"
self::VERSION # => "1.0.0"

def self.method
VERSION # => "1.8.7"
end
method
end

# going back through ruby versions
# I wasn't able to get these to print
# the ruby version until 1.7.1
# thanks, ruby-versions.net :slight_smile:
Foo::VERSION # => "1.0.0"
Foo::VERSION # => "1.0.0"

Yes, it would be.

···

On Nov 25, 9:03 am, Robert Klemme <shortcut...@googlemail.com> wrote:

Is this really an issue with ::VERSION? To me this rather looks like
an issue with lookup logic (either the general or yours) since the
same would apply to all other constants, wouldn't it?

> Ruby's VERSION constant is getting in the way of using #const_missing
> in my module. Here's some example code:

> module Foo
> def self.const_data
> @const_data ||= { 'version' => '1.0.0' }
> end

> def self.const_missing(name)
> key = name.to_s.downcase
> const_data[key] || super(name)
> end
> end

> Foo::VERSION #=> '1.8.7'

> How can I fix this?

What would ::const_data provide that Module#constants, Module#const_get and Module#const_set and direct constant access don't provide? If it's something legitimate, invert ::const_data to reference real constants via introspection and get rid of const_missing.

I could, but I wanted to lazy load the information b/c it is being
read from a file, and in most usecases will not be used. The reason I
am using constants is simply b/c it's customary in this case as the
information is project metadata, such as VERSION.

> I tried `remove_const(:VERSION)` at the toplevel but discovered that
> some Ruby library don't like that (sorry, can't recall which it was
> off hand).

File a bug, they should be using RUBY_VERSION.

Will do. I tracked it down to a Ruby 1.8.7:

  e2mmap.rb:fail "Use Ruby 1.1" if VERSION < "1.1"

···

On Dec 13, 1:21 pm, Eric Hodel <drbr...@segment7.net> wrote:

On Nov 25, 2010, at 05:54, Intransition wrote: