Anyone else having classes not showing up in modules?

I have a class in a module that isn’t accessible from outside the module and won’t show up in the module’s constant list. The other class I have does. Also, the include directive doesn’t seem to be working consistently. I was just wondering if anyone else have had such problems in ruby for SU 2017?

None that I know of, but …

… we could not give you advice without know how you defined your namespace module and classes. Can you post a barebones snippet of the declarations. (It need not have the internal module of class code included.)

Also … since there is very little reason to ever have any code evaluating outside your extension submodule, accessing a submodule’s classes should not be an issue. Again please sho how you are trying to access these classes.

I’ll see if I can get to that when I can.

Yeah, well, I was trying to instantiate one class within another’s sibling class’ method. Also, saw this from the ruby console when executing stuff directly.

module SomeCompany
  module SomeExtension

    class One
      attr_accessor :args
      def initialize(*args)
        @args = args
      end
    end

    class Two
      def self.get_one
        One.new("This is from Two.")
      end
    end

    def self.test
      one = Two.get_one
      puts "one's first arg is: #{one.args.first.inspect}"
    end

  end
end

From the console …

SomeCompany::SomeExtension.test

… produces …

one's first arg is: "This is from Two."

So, normally a sibling class can see it’s siblings. But the example shows access from a class method.

Were you attempting from an instance method that was held in another context ?

No, everything atm is in one file and one module. It was weird because everything was working for a while, but eventually it broke for no apparent reason. The only thing I can think of is that the module got too big, which seems unlikely, but I don’t see anything else that really changed. Of course code was added, but there weren’t any reported parse errors and the code appears to work as I expected it to sans the two issues I stated.

The most common would be a missing end or } which results in …

Error: #<SyntaxError: <main>:8: syntax error, unexpected end-of-input, expecting `end'>
SketchUp:in `eval'

Using a good code editor that matches up blocks reduces this kind of error.

Just a FYI … the interpretive module block form means …
“open the named module for edit and create if needed”.

So a module may be opened for code additions or changes (ie, method redefinitions, etc.) in any number of subsequent files. It is one of the things I love about Ruby (and dislike about Python where the name of the file controls the module encapsulation.)

Extensions having large code are often broken up categorically into smaller files and the set is loaded by a “loader” file. The “loader” .rb is what the extension registrar specifies as the 2nd argument in the SketchupExtension constructor call.

Anyway … back on topic.

You can use the :: scope operator to tell Ruby how to find things.
For example from another method in class Two I could make a call like:

  ::SomeCompany::SomeExtension::One.some_class_method_call("text")

… and Ruby would know to begin it’s search for the named objects in the top level ObjectSpace (the :: prefix,) and then on down the following qualification.

Yeah, tried the scope operator, that’s why I also said

I actually mean just that. MyModule.constants doesn’t contain that class, though it does have the other one. As I’ve not touched anything that low level, I don’t know how that can happen. The lowest level that I’ve touched is defining a method_missing method which is located in both classes, due the afore mentioned issue with include. That redirects the search to the enclosing module if a method isn’t found and only if it exists there.

And we neither unless we could see how the classes were defined.

But this is not to say that we’ve never encountered memory errors that made things run weirdly.
(When this happens I always suggest rebooting the machine.)

A note on overriding method_missing, … make sure that you always call super.

This is what I have:

   def method_missing(method, *args, &block)
        if ::MyModule.respond_to?(method)
            ::MyModule.send(method, *args, &block)
        else
            super
        end
    end

Are you saying that super should be executed in all cases? That doesn’t sound right.

There is chapter from a well respected Ruby book I’ll see if I can post the link to.

ADD: I believe it is “Ruby Best Practices” pg 68.
(… link is in my Ruby Resources book list.)

But if I remember correctly you do as you have done, when your override does not handle the situation then you pass it along to the normal definition of method_missing which is usually the default defined in BasicObject. (Note that the example in the Ruby docs is poorly written in this respect.)


Re, your snippet. Seems like it would not work because it would only get called if MyModule did not respond to the method, yet then the if clause calls the missing method.

I don’t understand.

method is called in ::MyModule context iff ::MyModule has a method called method. Otherwise, it’ll pass the call down to the super. Where did you get not from?

Nevermind. I didn’t understand that you’ve overridden in the classes to call some backup in their parent module. (You’ve edited that reply several times. I thought that the method_missing override was in the module.)

I cannot fully understand your issues because you haven’t posted code yet.