• Login
sketchucation logo sketchucation
  • Login
⚠️ Attention | Having issues with Sketchucation Tools 5? Report Here

Namespace question on noob level

Scheduled Pinned Locked Moved Developers' Forum
16 Posts 3 Posters 408 Views 3 Watching
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.
  • L Offline
    liquid98
    last edited by 10 Aug 2012, 14:24

    Hello everybody,

    I have a script that contains several methods that are useful in other scripts. I called it shared.rb.

    It's contents:

    
    require 'sketchup.rb'
    
    module AA
    
    	def self.usefull1
    		# code here
    	end
    
    	def self.usefull2
    		# code here
    	end
    
    	def self.usefull3
    		# code here
    	end
    
    end
    

    So I can use the methods in other files like this:

    ` require 'sketchup.rb'
    require 'shared.rb'

    ...
    AA.usefull1`

    My question: is there a possibility to avoid prefixing the Module name?
    Like:
    ` require 'sketchup.rb'
    require 'shared.rb'

    ...
    usefull1`

    Tnx, liquid

    Things that flourish fall into decay. This is not-Tao, And what is not-Tao soon ends ~ Lao tse

    1 Reply Last reply Reply Quote 0
    • S Offline
      sdmitch
      last edited by 10 Aug 2012, 15:10

      No because it is in a module. You could only do that if you removed the module wrapper which is not recomended due to potential conflects with other scripts.

      Nothing is worthless, it can always be used as a bad example.

      http://sdmitch.blogspot.com/

      1 Reply Last reply Reply Quote 0
      • L Offline
        liquid98
        last edited by 10 Aug 2012, 15:54

        Hi Mitch,

        Thanx for your answer!

        Things that flourish fall into decay. This is not-Tao, And what is not-Tao soon ends ~ Lao tse

        1 Reply Last reply Reply Quote 0
        • D Offline
          Dan Rathbun
          last edited by 10 Aug 2012, 16:26

          @liquid98 said:

          My question: is there a possibility to avoid prefixing the Module name?
          Like:
          ` require 'sketchup.rb'
          require 'shared.rb'

          ...
          usefull1`

          Actually yes there is as long as you are always coding within some namespace. (Never create global methods.)

          1) First of all, your library module needs to be INSIDE your toplevel "Author" module.
          2) You need to make the module a double-duty Library/Mixin module, using the module_function method.

          file: "liquid/useful.rb":

          
          require 'sketchup.rb'
          
          module Liquid
            module Useful
          
              module_function
          
              def usefull1
                # code here
              end
          
              def usefull2
                # code here
              end
          
              def usefull3
                # code here
              end
          
            end # Useful
          end # Liquid
          

          Then in another file:

          
          require 'sketchup.rb'
          
          module Liquid
            module FancyPlugin
          
              require("liquid/useful.rb")
              include(Liquid;;Useful)
          
              puts( usefull1 ) if useful2
          
              # more code
          
            end # FancyPlugin
          end # Liquid
          

          πŸ’­ But never include() modules into the TOPLEVEL_BINDING, which is Object.

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • D Offline
            Dan Rathbun
            last edited by 10 Aug 2012, 17:20

            @liquid98 said:

            The require("liquid/useful.rb") line is mandatory inside the two modules 'Liquid' and 'FancyPlugin' ??

            NO

            @liquid98 said:

            Or is it also possible to put it among the first lines of the script?

            YES

            @liquid98 said:

            What do you mean by

            'But never include() modules into the TOPLEVEL_BINDING, which is Object. ? '

            Unwrapped methods are evaluated in Object, and become global methods. They get inherited by EVERYONE's modules and classes, and make us angry. πŸ‘Ώ
            The same for constants, instance variables and class variables.

            Just plain code within your own namespace, and we will love you. πŸ˜†

            I'm not here much anymore.

            1 Reply Last reply Reply Quote 0
            • D Offline
              Dan Rathbun
              last edited by 10 Aug 2012, 17:27

              @liquid98 said:

              So every script should be in a double namespace ?? (Liquid and Name).. with or without loading other scripts ??

              All your code needs to be within YOUR namespace (whatever you decide to call it.)

              You will find that you wish to separate each of your plugins from one another. So each goes in it's own sub-module namespace, so they do not clash with each other.

              Also in the "Plugins" directory.. your files need to go in YOUR "author" sub-directory.
              You will want to maintain your plugins separately, so each should go in a sub-dir of your "author" directory.

              I suggest having the directory names and modules the same. It helps syncing up the require arguments with the include or extend arguments.

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • L Offline
                liquid98
                last edited by 10 Aug 2012, 17:54

                Cooool! Thanx, I was hoping for this! πŸ‘

                Global methods: just methods without any namespace? -- Refrain from using them, right?

                So every script should be in a double namespace ?? (Liquid and Name).. with or without loading other scripts ??

                What do you mean by:

                'But never include() modules into the TOPLEVEL_BINDING, which is Object. ? '

                EDIT:
                require("liquid/useful.rb") include(Liquid::Useful)
                Should be placed outside the modules!!

                Thnx

                Things that flourish fall into decay. This is not-Tao, And what is not-Tao soon ends ~ Lao tse

                1 Reply Last reply Reply Quote 0
                • L Offline
                  liquid98
                  last edited by 10 Aug 2012, 18:12

                  Thanx again Dan,

                  Really beautiful to see it running this way!! πŸ˜„ πŸ˜„
                  This trick is not widely known according to my grep.. πŸ€“

                  Liquid

                  Things that flourish fall into decay. This is not-Tao, And what is not-Tao soon ends ~ Lao tse

                  1 Reply Last reply Reply Quote 0
                  • L Offline
                    liquid98
                    last edited by 10 Aug 2012, 20:24

                    Hi Dan,

                    Thnx for the information. The next script I've written will have this namespace treatment!
                    By the way I found that calling :

                    require("liquid/useful.rb")
                    include(Liquid;;Useful)
                    

                    only works outside the module definition.. ❓ ❓

                    edit: Other question: Is there some evil in using load instead of require?

                    Things that flourish fall into decay. This is not-Tao, And what is not-Tao soon ends ~ Lao tse

                    1 Reply Last reply Reply Quote 0
                    • D Offline
                      Dan Rathbun
                      last edited by 11 Aug 2012, 03:58

                      @liquid98 said:

                      By the way I found that calling :

                      require("liquid/useful.rb")
                      > include(Liquid;;Useful)
                      

                      only works outside the module definition.. ❓ ❓

                      NO.. This is not true, .. and Do not do this. If you do, you will add methods to EVERYONE's modules and classes, not just yours.

                      If you cannot get it to work, then you are doing something incorrect.

                      FYI: The mixin methods, in a mixin module, must be defined as instance methods, without a self. before the name.

                      I'm not here much anymore.

                      1 Reply Last reply Reply Quote 0
                      • D Offline
                        Dan Rathbun
                        last edited by 11 Aug 2012, 04:10

                        [off:2wuy0iss]
                        @liquid98 said:

                        Other question: Is there some evil in using load instead of require?

                        They do different things:

                        require() checks the $LOADED_FEATURES (aka $",) array and only loads the file if it has not already been loaded, and if it does (without error since v1.8.4, or so,) adds the filepath to that array. (Beware that v1.8.0 adds the filepath before the load attempt, so under Windows Sketchup < 8.x, that is still running v1.8.0, filepaths for failed files will exist in $".)

                        load() does not check $", always attempts to load the file, even it it was previously loaded, and does not push any filepaths into the $" array.

                        So.. we use load() during debugging, to re-load scripts, which will re-define methods with the new changes.

                        After release... require() is used so libraries are only loaded once.[/off:2wuy0iss]

                        I'm not here much anymore.

                        1 Reply Last reply Reply Quote 0
                        • D Offline
                          Dan Rathbun
                          last edited by 11 Aug 2012, 04:23

                          @liquid98 said:

                          This trick is not widely known according to my grep..

                          I will need to disagree. It is not a "trick."

                          Mixin Library Modules, that are used with include() and extend(), is basic Ruby (perhaps in the second semester course,) but still one of the fundamental principals of the dynamic nature built into Ruby.

                          The problem is that most people are impatient, and refuse to read the Ruby textbook, to learn the fundamentals first. They read the first chapter and start hacking away.

                          My Question to YOU: Have YOU read the book yet ??
                          (I do not think you have given your questions.)

                          It is in the "doc" folder of the the Full Ruby install, usually on Windows:
                          %(#004000)["C:/Ruby186/doc/ProgrammingRuby.chm"]

                          Also online at:
                          http://phrogz.net/ProgrammingRuby/frameset.html


                          Am I the only person in the world, who read this book cover-to-cover, before ever writing a single line of Ruby ?? πŸ˜’

                          Doing so saved me much frustration ! Although that book is old (... written in the v1.6.x days,) it is still valid, and I still refer to it often.

                          I'm not here much anymore.

                          1 Reply Last reply Reply Quote 0
                          • L Offline
                            liquid98
                            last edited by 11 Aug 2012, 10:45

                            Dan,

                            No I haven't read the book yet. Though I scraped my information from several places, like this forum, google, other books, Rubydocs
                            'Automatic Sketchup', etc.

                            In my point of view 90% of ruby scripting for sketchup is just using the Ruby API. The other 10 % is a set of rules cq best practices
                            to manage the code in a efficient way.

                            Though I thank you for your suggestion, I have I complete folder of URL's with ruby books, to impressive to start with..
                            So a good starting point is welcome.

                            Rene

                            Things that flourish fall into decay. This is not-Tao, And what is not-Tao soon ends ~ Lao tse

                            1 Reply Last reply Reply Quote 0
                            • L Offline
                              liquid98
                              last edited by 16 Aug 2012, 19:32

                              @dan rathbun said:

                              @liquid98 said:

                              By the way I found that calling :

                              require("liquid/useful.rb")
                              > > include(Liquid;;Useful)
                              

                              only works outside the module definition.. ❓ ❓

                              NO.. This is not true, .. and Do not do this. If you do, you will add methods to EVERYONE's modules and classes, not just yours.

                              If you cannot get it to work, then you are doing something incorrect.

                              FYI: The mixin methods, in a mixin module, must be defined as instance methods, without a self. before the name.

                              Hi Dan,

                              I just copy pasted your example into two files:
                              It works only if

                              require("useful.rb")
                              include(Liquid;;Useful)
                              

                              is outside the modules.
                              Can you please take a look??

                              Thnx,

                              Rene


                              mixin test

                              Things that flourish fall into decay. This is not-Tao, And what is not-Tao soon ends ~ Lao tse

                              1 Reply Last reply Reply Quote 0
                              • D Offline
                                Dan Rathbun
                                last edited by 17 Aug 2012, 11:40

                                Ok got it.. you need to use a proxy class inside a module:

                                (1) The word useful has only 1 "L", by the way.

                                "Plugins/liquid/useful.rb"

                                  module Liquid
                                
                                    MENU = UI.menu('Plugins').add_submenu('Liquid')
                                
                                    module Useful
                                
                                      module_function
                                
                                      def useful_1()
                                        msg = "I am method useful_1()."
                                        puts( msg )
                                        return msg
                                      end
                                
                                      def useful_2()
                                        msg = "I am method useful_1()."
                                        puts( msg )
                                        return msg
                                      end
                                
                                      def useful_3()
                                        msg = "I am method useful_1()."
                                        puts( msg )
                                        return msg
                                      end
                                
                                    end # Useful
                                  end # Liquid
                                
                                

                                "Plugins/liquid/fancy.rb"

                                  require("liquid/useful.rb")
                                
                                  module Liquid
                                
                                    module Fancy
                                    
                                      class << self # proxy class
                                
                                        include(Liquid;;Useful)
                                
                                      end # proxy class
                                
                                      useful_1()
                                
                                    end # module Fancy
                                
                                  end # module Liquid
                                

                                But for a custom class, no proxy class is needed:
                                "Plugins/liquid/fancytool.rb"

                                  require("sketchup.rb")
                                  require("liquid/useful.rb")
                                
                                  module Liquid
                                
                                    module Fancy
                                    
                                      class FancyTool
                                
                                        include(Liquid;;Useful)
                                
                                        def activate()
                                          UI.messagebox( useful_1() )
                                          Sketchup.active_model.select_tool(nil)
                                        end
                                
                                      end # class
                                
                                      unless file_loaded?('Liquid;;Fancy;;FancyTool')
                                        @@tool = FancyTool.new()
                                        Liquid;;MENU.add_item('FancyTool') { 
                                          Sketchup.active_model.select_tool(@@tool)
                                        }
                                        file_loaded('Liquid;;Fancy;;FancyTool')
                                      end # unless
                                
                                    end # module Fancy
                                
                                  end # module Liquid
                                

                                I'm not here much anymore.

                                1 Reply Last reply Reply Quote 0
                                • L Offline
                                  liquid98
                                  last edited by 18 Aug 2012, 14:51

                                  Off topic:

                                  @unknownuser said:

                                  (1) The word useful has only 1 "L", by the way.

                                  thanx for your correction, the English language is not my mother language as you might have noticed..
                                  /Off topic

                                  All code is safe now and my code works like a charm, so thanx for your help. And yes I SHALL read the book before
                                  I come here and ask questions like this.. πŸ˜„

                                  Things that flourish fall into decay. This is not-Tao, And what is not-Tao soon ends ~ Lao tse

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

                                  Advertisement