sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    [??] How to pass a variable from main.rb to a boxtool

    Scheduled Pinned Locked Moved Developers' Forum
    11 Posts 4 Posters 170 Views 4 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.
    • A Offline
      Aerilius
      last edited by

      @unknownuser said:

      @boxheight = 100 # It's a variable inside the tool, but it dont work!

      In main.rb, it's an (undefined) variable outside the tool.
      In rs_boxtool.rb, it's an instance variable that does not exist as long as you haven't created an instance of the class (that's what you do later with boxtool = BOX_tool.new)

      One possibility is to make the instance variable available from outside via attr_accessor [the link is for Module but it works for class instances too (?)]. You can then change the instance variable (under the condition that you first create the instance):

      require ('as_plugins/as_rubyeditor/snippets/rs_boxtool.rb')
      boxtool = BOX_tool.new
      boxtool.boxheight = 100
      Sketchup.active_model.select_tool boxtool
      
      class BOX_tool
        attr_accessor ;boxheight
        # ...
      end
      

      attribute_accessor basically creates a new method (with the same name like the variable) to change the variable's value.

      1 Reply Last reply Reply Quote 0
      • TIGT Offline
        TIG Moderator
        last edited by

        Typically...
        Common named Modules share @variables across sessions, until overwritten.
        Common named Classes share @@variables across sessions, AND @variables per class-instance, until overwritten.

        TIG

        1 Reply Last reply Reply Quote 0
        • Dan RathbunD Offline
          Dan Rathbun
          last edited by

          @rvs1977 said:

          I would like to pass a variable from "main.rb" to "rs_boxtool.rb", ....

          In Ruby.. the file does not create a namespace context (like it does in Python.)

          In other words... the beginning and end of a file, means nothing to Ruby. It is not the beginning and ending of code, in Ruby's eyes, it's just a bunch of lines of code.

          You must explicitly declare your own namespace (using module,) in BOTH files, so that the code from each file, runs within the same context. In that way.. the files can access variables defined in either file.

          If you do not wrap your code within an author module (say module RVS as an example,) then the code will run within the TOPLEVEL_BINDING which is class Object.
          The problem is that EVERYTHING in Ruby is an object, and therefor a subclass of Object, and your variables, methods, etc. in the unwrapped code will propagate into EVERYONE's classes and modules.. ie ALL other objects.

          See these threads where other persons asked almost the same question:
          how toget a Settings Menu to communicate with a Main Menu?
          and:
          Program format

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • R Offline
            rvs1977
            last edited by

            First of all, thank you for all the answers. Its really helpful.

            Even though its a little abstract to me right now, I know which direction to go. I belive the answer is using an author module. I will try to find out the difference between module and class


            Get a Ruby

            1 Reply Last reply Reply Quote 0
            • Dan RathbunD Offline
              Dan Rathbun
              last edited by

              @rvs1977 said:

              I will try to find out the difference between module and class

              The difference is simple:

              class Class is a subclass of class Module.

              Generally... when you need ONE copy of some code, you use a Module. (Also when you need to create a namespace, or subnamespaces, to separate the execution context of some code, from all other code,... be it your code or the code from the rest of the world.)

              When you need instances (multiple copies,) of some code, you use a Class, and create instances using the class' constructor method new(). (There are situations when you must use a Class, but only ONE instance is allowed. This is called a singleton class.)

              Good rules to follow for classes:

              1) Only Ruby base classes should be defined as a global class, at the toplevel.

              2) Author classes that will be used by more than one of your plugins, should be defined, just inside your author toplevel namespace (module.)

              3) Each one of your plugins should be defined within a submodule (at some nesting level that YOU choose,) inside your author toplevel namespace (module.)

              4) An author class, that is specific to a certain plugin, should be defined within that plugin's submodule.

              Just as you would organize your directory hierarchy, where your code files reside... you can organize your namespace hierarchy in the same manner.

              I talk about it in this tutorial:
              [ Code ] SketchupExtension and rbs rubies

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                BTW.. did you install the full Ruby version ??
                Ruby (v1.8.6-p287) Windows One-Click Installer

                When you do.. you will have the full CHM file for
                "Programming Ruby - The Pragmatic Programmer's Guide, 1st Ed."
                in your "C:/Ruby186/doc" directory.

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • R Offline
                  rvs1977
                  last edited by

                  I get the point using namespaces, so I decided to find out how module works by making the simpelts possible example... and it dont work πŸ˜•

                  Again with 2 files:

                  • rs_main.rb, and
                  • rs_moduletest.rb

                  From rs_main.rb I call a method defined inside rs_moduletest.rb. The method then should write in a messagebox "Hello World".

                  rs_main.rb:

                  module RVS; end
                  module RVS;;MyPlugin 
                  
                      # declare module vars and constants first
                      @@myHelloVar = 'Hello World'
                      
                      
                      # require other parts of this plugin;
                      require('as_plugins/as_rubyeditor/snippets/rs_moduletest.rb')
                      
                      # main plugin script, menu items, etc.
                      MyPlugin.test() # Calling the test-method from rs_moduletest.rb
                  
                  end #module RVS;;MyPlugin 
                  

                  rs_moduletest.rb

                  module RVS;;MyPlugin 
                  	public
                  	def self.test ()
                  		UI.messagebox @@myHelloVar 
                  	end
                  	
                  end #module RVS;;MyPlugin 
                  

                  how should this be written to work?


                  Get a Ruby

                  1 Reply Last reply Reply Quote 0
                  • R Offline
                    rvs1977
                    last edited by

                    @dan rathbun said:

                    BTW.. did you install the full Ruby version ??
                    Ruby (v1.8.6-p287) Windows One-Click Installer

                    When you do.. you will have the full CHM file for
                    "Programming Ruby - The Pragmatic Programmer's Guide, 1st Ed."
                    in your "C:/Ruby186/doc" directory.

                    No I havn't. But I will πŸ˜„


                    Get a Ruby

                    1 Reply Last reply Reply Quote 0
                    • Dan RathbunD Offline
                      Dan Rathbun
                      last edited by

                      "rs_moduletest.rb":
                      remove the space between the method name and the opening "(" for the argument list. Never put spaces between them, either when defining them, or calling a method. An error can occur that gives very weird messages in Ruby 1.8.6.

                      "rs_main.rb":
                      What you are doing wrong is trying to call a method from within namespace RVS::MyPlugin that is first looking within that namespace for a constant identifying an object named MyPlugin, but there not one.. so second, Ruby goes up to the top level and looks there again for a constant identifying an object named MyPlugin, but again does not find one, so it raises a NameError exception.

                      Either:

                      1) use the self keyword, which within a module, returns a reference to the module itself.
                      so line 12, can be:
                      self.test()

                      or 2) define your plugin methods within a proxy class block:
                      "rs_moduletest.rb":

                      module RVS;;MyPlugin
                        class << self
                          public
                          def test()
                            UI.messagebox( @@myHelloVar )
                          end
                        end # proxy class 
                      end #module RVS;;MyPlugin
                      

                      Notice how in this case you do not define the method prefixed with " self." ??
                      then in "rs_main.rb", you simply call the method by name only, as you would in a class instance:
                      test()
                      You may also use the global method private (instead of public,) if you wished your module's test method to be called only (easily,) from within it's module.

                      Also... the method test() is a very important global method for testing files and directories, and it is inherited by your modules.
                      But since, they are YOUR modules, you are allowed to override inherited methods. If you still wanted access to the global method, you would need to qualify it's call as:
                      Kernel.test(?d,"C:/Ruby186")
                      which tests if "C:/Ruby186" exists and is a directory.

                      I'm not here much anymore.

                      1 Reply Last reply Reply Quote 0
                      • R Offline
                        rvs1977
                        last edited by

                        Finally it works!!... πŸ˜„

                        BUT I had to move the rs_main.rb from the "\Plugins\as_plugins\as_rubyeditor\snippets"-folder to the "\Plugins"-folder, and then restart SU. At start up it showed the Alertbox "Helle World".

                        BUT It won't work if I use the playbutton in AS-code editor. It seems like, when using modules, it has to be loaded into SU at startup.

                        I wonder if there is a way to come around this?

                        EDITED 1: It can be run directly from the snippet folder with ruby console (then SU requires no restart):
                        load 'c:\path to the program\Google SketchUp 7\Plugins\as_plugins\as_rubyeditor\snippets\rs_main.rb'

                        EDITED 2: in rs_main.rb require is changed to load. Then it updates the variables when its changed.

                        So far so good! Thank you...


                        Get a Ruby

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

                        Advertisement