Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.6.7
    • Fix Version/s: JRuby 1.7.0.pre1
    • Component/s: None
    • Labels:
      None
    • Environment:
      Windows 7
    • Testcase included:
      yes
    • Number of attachments :
      1

      Description

      Kernel.autoload doesn't seem to work with the Time class, while Module.autoload does work.

      % jruby -v
      jruby 1.6.7 (ruby-1.8.7-p357) (2012-02-22 3e82bc8) (Java HotSpot(TM) Client VM 1.6.0_17) [Windows 7-x86-java]

      Run the following script:

      autoload :Bar, 'bar'
      puts autoload?(:Bar)

      autoload :Time, 'time'
      puts autoload?(:Time)

      module Foo
      end

      Foo.autoload :Time, 'time'
      puts Foo.autoload?(:Time)

      I see the following output:

      bar
      nil
      time

      when I would expect to see the following:

      bar
      time
      time

      Unit test file attached to demonstrate the bug.

        Issue Links

          Activity

          Hide
          Charles Oliver Nutter added a comment -

          Rubinius fails this in the same way we do...

          Show
          Charles Oliver Nutter added a comment - Rubinius fails this in the same way we do...
          Hide
          Charles Oliver Nutter added a comment -

          Ok, so the actual problem here is due to calling autoload as a Kernel method from within an instance method.

          system ~/projects/jruby $ ruby1.9.3 -e "class Foo; def go; autoload :Bar, 'bar'; end; end; f = Foo.new; f.go; p Foo.autoload? :Bar"
          "bar"
          
          system ~/projects/jruby $ jruby -e "class Foo; def go; autoload :Bar, 'bar'; end; end; f = Foo.new; f.go; p Foo.autoload? :Bar"
          nil
          

          In Kernel#autoload we call a method getModuleForAutoload to determine the module in which the autoload should be defined. If self is a module or class, we use that. Otherwise, we try to define the autoload on Object directly. That causes the Time autoload to fail here because Time already exists on Object.

          MRI uses the current cbase class/module as the location to define the class for autoload. This allows it to define the autoload on the current object's class.

          Show
          Charles Oliver Nutter added a comment - Ok, so the actual problem here is due to calling autoload as a Kernel method from within an instance method. system ~/projects/jruby $ ruby1.9.3 -e "class Foo; def go; autoload :Bar, 'bar'; end; end; f = Foo.new; f.go; p Foo.autoload? :Bar" "bar" system ~/projects/jruby $ jruby -e "class Foo; def go; autoload :Bar, 'bar'; end; end; f = Foo.new; f.go; p Foo.autoload? :Bar" nil In Kernel#autoload we call a method getModuleForAutoload to determine the module in which the autoload should be defined. If self is a module or class, we use that. Otherwise, we try to define the autoload on Object directly. That causes the Time autoload to fail here because Time already exists on Object. MRI uses the current cbase class/module as the location to define the class for autoload. This allows it to define the autoload on the current object's class.
          Hide
          Charles Oliver Nutter added a comment -

          Oops, I committed a fix for this one instead of for JRUBY-6508. Here's the commit:

          commit 195b90243b343619b462324c0eafcf97531b1f50
          Author: Charles Oliver Nutter <headius@headius.com>
          Date:   Wed Apr 4 10:56:43 2012 -0500
          
              Fix JRUBY-6570: autoload :Time, 'time' doesn't work
              
              Instead of always using Object when calling autoload from an
              instance method, we use self's real class (skipping singletons)
              as the autoload location. This isn't exactly how MRI does it
              (they use cbase, which I think is euivalent to 1.8's ruby_class),
              but it should be correct for the majority of cases.
          
          Show
          Charles Oliver Nutter added a comment - Oops, I committed a fix for this one instead of for JRUBY-6508 . Here's the commit: commit 195b90243b343619b462324c0eafcf97531b1f50 Author: Charles Oliver Nutter <headius@headius.com> Date: Wed Apr 4 10:56:43 2012 -0500 Fix JRUBY-6570: autoload :Time, 'time' doesn't work Instead of always using Object when calling autoload from an instance method, we use self's real class (skipping singletons) as the autoload location. This isn't exactly how MRI does it (they use cbase, which I think is euivalent to 1.8's ruby_class), but it should be correct for the majority of cases.
          Hide
          Charles Oliver Nutter added a comment -

          Reopening to resolve as fixed, since this issue may be slightly different from JRUBY-6508.

          Show
          Charles Oliver Nutter added a comment - Reopening to resolve as fixed, since this issue may be slightly different from JRUBY-6508 .
          Hide
          Jeff Solomon added a comment -

          Thank you Charles!

          Show
          Jeff Solomon added a comment - Thank you Charles!

            People

            • Assignee:
              Charles Oliver Nutter
              Reporter:
              Jeff Solomon
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: