• Login
sketchucation logo sketchucation
  • Login
ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

Ruby Module Variables

Scheduled Pinned Locked Moved Developers' Forum
10 Posts 3 Posters 2.3k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    Anton_S
    last edited by 15 Apr 2012, 04:10

    Based on the reference: Module Variables , I figured that it's valid to create instance variables inside the Module. I tested it on SU via Ruby and it all worked, without any conserns. Though, some of Ruby things began bugging me, and thus I need a good confirmination.

    1st: Creating instance variables in module namespace is valid, though is it right and why?

    2nd: Since, you can't create an instance of a module (SomeModule.new = No function such as new) then, why are there things such as module instance methods (def someMethod) and module class methods (def self.someMethod)?

    3rd: Getting even deeper, I figured that it is valid to create constants inside the class. They act the same way as class variables, though as usual ruby would warn once the constant is assigned a different value. So, is it also right to initiate constants inside the class namespace?

    4th: What is a difference bettween instance variables and class variables in the module?

    1 Reply Last reply Reply Quote 0
    • D Offline
      Dan Rathbun
      last edited by 15 Apr 2012, 11:26

      @anton_s said:

      2nd: Since, you can't create an instance of a module (SomeModule.new = No function such as new)...

      WRONG

      class Module, like ALL Ruby objects, has a new() constructor class method (which is a block form method,) ie:

      Anton = Module.new() {
        @color = blue
        def self.get_color()
          @color
        end
      }
      

      Remember that a Ruby script is for humans to read.. Ruby does not really use it. The interpreter reads the script " module Anton" and translates it into a constructor call (similar to the above example,) but in C code.

      @anton_s said:

      ... then, why are there things such as module instance methods (def someMethod) and module class methods (def self.someMethod)?

      Because modules can be the library type (best used with module/class variables and module/class methods,) OR the "Mixin" type, which are used to mixin instance variables and instance methods into custom classes. (You can also create a hybrid that is both types, like the Math module is.)
      So.. read up on Mixin Modules.

      I'm not here much anymore.

      1 Reply Last reply Reply Quote 0
      • J Offline
        Jim
        last edited by 15 Apr 2012, 11:36

        Great questions, Anton.

        Around here modules are used mainly as namespaces to wrap methods and avoid method name conflicts. More typically in ruby, modules are used to implement the object-oriented programming concept called multiple inheritance (called mixins in Ruby.)

        As far as I know, a instance variable, a class variable, and a constant will all have the same visibility (scope) when defined at the top-level of a module. They will all be visible everywhere within the module namespace, including classes and other modules defined within the module. A unique feature of Ruby is that these same objects (classes, modules, variables) are visible across files if the files use the same names.

        Which is "right" may come down to convention and personal preference.

        Hi

        1 Reply Last reply Reply Quote 0
        • D Offline
          Dan Rathbun
          last edited by 15 Apr 2012, 11:39

          @anton_s said:

          3rd: Getting even deeper, I figured that it is valid to create constants inside the class. They act the same way as class variables, though as usual ruby would warn once the constant is assigned a different value. So, is it also right to initiate constants inside the class namespace?

          YES you may. But do not use Constants in place of variables. (At some time in the future the Core guys are not going to let us change them.)

          To prevent the warning (say during debugging... wrap Constant definitions within a "Run Once" conditional.

          unless file_loaded?(__FILE__)
            DELIMITER = ","
            RECORD_END = "\n"
          end
          

          or:
          DELIMITER = "," unless defined?(DELIMITER)

          or
          DELIMITER ||= ","

          If you really must change a Constant, you can use the remove_constant(:CONSTANTNAME) private method within your namespace first, then redefine it.. and there will be no warning output.

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • D Offline
            Dan Rathbun
            last edited by 15 Apr 2012, 12:06

            @anton_s said:

            1st: Creating instance variables in module namespace is valid, though is it right and why?

            What Jim says is true.. personal preference.. but I will usually advise using module variables for library modules and namespaces, and save instance variables for mixin modules and classes.

            But Ruby is designed to be multi-paradigm, so you can do things in the way you feel most comfortable.

            @anton_s said:

            4th: What is a difference bettween instance variables and class variables in the module?

            In modules, it's subtle.

            If you use a proxy class block within your module (which makes things A WHOLE LOT EASIER...) then Constants and module variables need to be defined outside the proxy class block, but instance variables need to be defined within it:

            require('sketchup.rb')
            module Anton;;FancyPlugin
            
              unless file_loaded?(File.basename(__FILE__))
            
                # Constants
                Border = "blue"
            
                # Module Vars
                @@opts = {}
            
              end
            
              class << self # PROXY CLASS
            
                # INSTANCE VARS
                @counter = 0
                @limit = 100
            
                @@opts[;limit]= @limit
            
                def set_limit(arg=100)
                  if arg.is_a?(Numeric)
                    @limit = arg.to_i
                    @@opts[;limit]=@limit
                  end
                end
            
              end # PROXY CLASS
            
              # We can call methods in the proxy class
              # from inside module without qualification;
              set_limit(99)
            
              file_loaded(File.basename(__FILE__))
            
            end # module Anton;;FancyPlugin
            
            # We can call methods in the proxy class
            # from outside the module WITH qualification;
            Anton;;FancyPlugin.set_limit(125)
            
            

            I'm not here much anymore.

            1 Reply Last reply Reply Quote 0
            • A Offline
              Anton_S
              last edited by 15 Apr 2012, 21:22

              Thanks, for a great replie(s) Dan and Jim

              Well, isn't this:

              @dan rathbun said:

              
              > Anton = Module.new() {
              >   @color = 'blue'
              >   def self.get_color()
              >     @color
              >   end
              > }
              > 
              

              the same as this:?

              module Anton
                @color = 'blue'
                def self.get_color()
                  @color
                end
              end
              

              I don't see any difference in these


              @dan rathbun said:

              Because modules can be the library type (best used with module/class variables and module/class methods,) OR the "Mixin" type, which are used to mixin instance variables and instance methods into custom classes. (You can also create a hybrid that is both types, like the Math module is.)
              So.. read up on Mixin Modules.

              Found a really good explanation here , thanks 😄

              1 Reply Last reply Reply Quote 0
              • A Offline
                Anton_S
                last edited by 15 Apr 2012, 21:32

                @jim said:

                As far as I know, a instance variable, a class variable, and a constant will all have the same visibility (scope) when defined at the top-level of a module. They will all be visible everywhere within the module namespace, including classes and other modules defined within the module. A unique feature of Ruby is that these same objects (classes, modules, variables) are visible across files if the files use the same names.

                Which is "right" may come down to convention and personal preference.

                Alright, so are the two namespaces below right and which of them do you prefer better:?

                module CandiesM
                  @@count ||= 0
                  def self.buy(); @@count += 1; end
                end
                
                class CandiesC
                  @@count ||= 0
                  def self.buy(); @@count += 1; end
                end
                
                1 Reply Last reply Reply Quote 0
                • D Offline
                  Dan Rathbun
                  last edited by 16 Apr 2012, 07:02

                  @anton_s said:

                  I don't see any difference in these

                  No kidding! That was exactly the point I was making.

                  I'm not here much anymore.

                  1 Reply Last reply Reply Quote 0
                  • D Offline
                    Dan Rathbun
                    last edited by 16 Apr 2012, 07:18

                    @anton_s said:

                    Alright, so are the two namespaces below right and which of them do you prefer better:?

                    This:

                    
                    module Anton
                    
                      module CandiesM
                        @@count ||= 0
                        def self.buy(); @@count += 1; end
                      end
                    
                      class CandiesC
                        @@count ||= 0
                        def self.buy(); @@count += 1; end
                      end
                    
                    end # module Anton
                    

                    All of your modules and/or classes need to be within your "author" namespace.
                    If you need one copy of some code, make it a module.
                    If you need multiple copies of some code, make it a class, and use multiple instances of the code.

                    I'm not here much anymore.

                    1 Reply Last reply Reply Quote 0
                    • A Offline
                      Anton_S
                      last edited by 16 Apr 2012, 18:37

                      @dan rathbun said:

                      All of your modules and/or classes need to be within your "author" namespace.
                      If you need one copy of some code, make it a module.
                      If you need multiple copies of some code, make it a class, and use multiple instances of the code.

                      Ok, good advice, thaks 😄 . Now I'm on my way to 'Keep on typing' the code.

                      1 Reply Last reply Reply Quote 0
                      • 1 / 1
                      1 / 1
                      • First post
                        1/10
                        Last post
                      Buy SketchPlus
                      Buy SUbD
                      Buy WrapR
                      Buy eBook
                      Buy Modelur
                      Buy Vertex Tools
                      Buy SketchCuisine
                      Buy FormFonts

                      Advertisement