Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None
    • Environment:
      jruby 1.6.0.dev (ruby 1.8.7 patchlevel 249) (2010-09-28 a49928c) (Java HotSpot(TM) Client VM 1.6.0_18) [Windows 7-x86-java]
    • Testcase included:
      yes
    • Number of attachments :
      0

      Description

      require'java'

      module M
      include_package "javax.swing"
      include_package "java.awt.image" # BufferedImage
      class ShowImage < JFrame
      BufferedImage.new
      end

      end

      $ jruby bad.rb
      bad.rb:7: uninitialized constant M::ShowImage::BufferedImage (NameError)

      unless I'm using it wrong...

        Activity

        Hide
        Roger Pack added a comment - - edited

        appears a work around is to reference it before needing it in the internal class:

          require'java'
         
          module M
            include_package "javax.swing"
            include_package "java.awt.image" # BufferedImage
            BufferedImage
            class ShowImage < JFrame
             BufferedImage.new
            end
        
          end
        
        Show
        Roger Pack added a comment - - edited appears a work around is to reference it before needing it in the internal class: require'java' module M include_package "javax.swing" include_package "java.awt.image" # BufferedImage BufferedImage class ShowImage < JFrame BufferedImage. new end end
        Hide
        Hiro Asari added a comment -

        Or use M:: prefix.

        module M
          include_package 'javax.swing'
          include_package 'java.awt.image'
        
          class ShowImage < JFrame
            M::BufferedImage.new 100,100, M::BufferedImage::TYPE_BYTE_GRAY
          end
        end
        
        Show
        Hiro Asari added a comment - Or use M:: prefix. module M include_package 'javax.swing' include_package 'java.awt.image' class ShowImage < JFrame M::BufferedImage.new 100,100, M::BufferedImage::TYPE_BYTE_GRAY end end
        Hide
        Charles Oliver Nutter added a comment -

        Because there's no standard API on the JVM for getting a list of all classes in a given package, include_package works by adding a const_missing hook. The unfortunate side effect is that what looks like normal constants (the const_missing-provided classes) do not propagate according to constant-scoping rules (since const_missing only fires on the actual class, not up-hierarchy or up-scope as constant lookups do).

        We have toyed with some utilities for actively adding constants during an include_package, but they're all only partial solutions and they all ignore the fact that new classes could be loaded into the same package later. As a result, there's no way to fix this.

        I recommend a pattern where you have a single Ruby file that defines a nice Ruby module that explicitly imports all classes you need. Add additional classes there, and avoid include_package if you want to have consistent constant scoping behavior.

        Show
        Charles Oliver Nutter added a comment - Because there's no standard API on the JVM for getting a list of all classes in a given package, include_package works by adding a const_missing hook. The unfortunate side effect is that what looks like normal constants (the const_missing-provided classes) do not propagate according to constant-scoping rules (since const_missing only fires on the actual class, not up-hierarchy or up-scope as constant lookups do). We have toyed with some utilities for actively adding constants during an include_package, but they're all only partial solutions and they all ignore the fact that new classes could be loaded into the same package later. As a result, there's no way to fix this. I recommend a pattern where you have a single Ruby file that defines a nice Ruby module that explicitly imports all classes you need. Add additional classes there, and avoid include_package if you want to have consistent constant scoping behavior.
        Hide
        Roger Pack added a comment -

        Is re-tooling const_missing (i.e. before doing const_missing, scan parents for included packages, check for classes) an option?

        If not maybe it would be useful to include a helper.

        Either one of the utilities you mentioned, just make it explicit that it only loads currently available classes, or some ruby helper that overrides const_missing, like

         
        module M
          class A
            redirect_const_missing_to(M)
          end
        end
        

        or some odd...

        Show
        Roger Pack added a comment - Is re-tooling const_missing (i.e. before doing const_missing, scan parents for included packages, check for classes) an option? If not maybe it would be useful to include a helper. Either one of the utilities you mentioned, just make it explicit that it only loads currently available classes, or some ruby helper that overrides const_missing, like module M class A redirect_const_missing_to(M) end end or some odd...
        Hide
        Charles Oliver Nutter added a comment -

        We could make include_package insert a special pseudo-module into the hierarchy that has extra smarts in its const lookup logic. This would allow the normal hierarchical constant search to be aware of package imports and run another check in addition to looking at the normal constant table.

        It would be a bit hacky, but it's doable...

        Show
        Charles Oliver Nutter added a comment - We could make include_package insert a special pseudo-module into the hierarchy that has extra smarts in its const lookup logic. This would allow the normal hierarchical constant search to be aware of package imports and run another check in addition to looking at the normal constant table. It would be a bit hacky, but it's doable...
        Hide
        Roger Pack added a comment -

        maybe there's a way to add something like

        class A
        include_package 'org.abcd'
        end

        ?

        that would be especially useful if it could be "global" or what not (like you can set it to make those classes available everywhere).

        Show
        Roger Pack added a comment - maybe there's a way to add something like class A include_package 'org.abcd' end ? that would be especially useful if it could be "global" or what not (like you can set it to make those classes available everywhere).
        Hide
        Roger Pack added a comment -

        For now you can do

        module M
        include_package 'javax.swing'
        [JButton, JFrame, JLabel]
        end

        which isn't too bad...if a work-around...

        Show
        Roger Pack added a comment - For now you can do module M include_package 'javax.swing' [JButton, JFrame, JLabel] end which isn't too bad...if a work-around...
        Hide
        Roger Pack added a comment -

        It might be a nice work around if either of these two were made possible:

        import 'java.io.*' # sucks in what classes it knows about -- this would be enough, or
        for class in java.io.enum_current_classes; import class; end
        

        Thoughts?
        =r

        Show
        Roger Pack added a comment - It might be a nice work around if either of these two were made possible: import 'java.io.*' # sucks in what classes it knows about -- this would be enough, or for class in java.io.enum_current_classes; import class; end Thoughts? =r
        Hide
        Charles Oliver Nutter added a comment -

        I've started a separate bug to discuss improvements to include_package here: http://jira.codehaus.org/browse/JRUBY-5558

        Show
        Charles Oliver Nutter added a comment - I've started a separate bug to discuss improvements to include_package here: http://jira.codehaus.org/browse/JRUBY-5558

          People

          • Assignee:
            Charles Oliver Nutter
            Reporter:
            Roger Pack
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: