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

    Iterator problem

    Scheduled Pinned Locked Moved Developers' Forum
    16 Posts 5 Posters 481 Views 5 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.
    • S Offline
      spireup
      last edited by

      Hi

      I would like to use the iterator idea in ruby for my own classes but am struggling.

      Heres an example thats not working

      
      if Widget.each = 0 
        
        then puts "nuo"
        
        else
          for myWidget in Widget.each
      
            puts myWidget.xPos
        
          end
      end
      
      

      Any thoughts?

      thanks

      Paul

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

        Paul

        Your syntax seems to be shot to pieces...
        What does 'Widget.each' generate ?? It needs a 'result' to work on like in the 'else' part!
        An 'if test' uses '==' not '='... UNLESS you are testing to see if something that is set is then =0 and then it returns true ??
        You don't need 'then' in your if's...
        You seem to be mixing up 'if' and 'each' strangely... can you please explain in 'words' what you want to do and what each 'class/method' does... otherwise we are struggling πŸ˜’

        TIG

        1 Reply Last reply Reply Quote 0
        • Chris FullmerC Offline
          Chris Fullmer
          last edited by

          if Widget.length == 0 
            
            puts "nuo"
            
            else
              Widget.each do |myWidget|
          
                puts myWidget.xPos
            
            end
          end
          

          I think this is what you're getting at, translated to ruby syntax, best as I can tell.

          Lately you've been tan, suspicious for the winter.
          All my Plugins I've written

          1 Reply Last reply Reply Quote 0
          • J Offline
            Jim
            last edited by

            But what property of the Widget is to be iterated?

            Very generically:

            
            class Container
              def each
                if block_given?
                  while(prop = next_property() != nil)
                    yield(prop) # yield what?
                  end
                end
              end
            end
            c = Container.new
            c.each{|t| puts t}
            
            

            But your class may use a built-in collection (like an Array) to store data internally, in which ase you can use the each method in your custom each method:

            
            class Container
              include Enumerable
              def initialize
                @data_ = []
              end
              def each
                if block_given?
                  @data_.each{ |d|  yield(d) }
                end
              end
            end
            c = Container.new
            c.each{|t| puts t}
            
            

            Once you define the each method, you can include Enumerable and get a bunch more iterators:

            Enumerable.instance_methods ["find_all", "sort_by", "collect", "include?", "detect", "max", "sort", "partition", "any?", "to_a", "reject", "zip", "find", "min", "member?", "entries", "inject", "all?", "select", "each_with_index", "grep", "map"]

            Hi

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

              Why not just define Widget to be a subclass of some standard class that has module Enumerable mixed-in?

              class Widget < Array
                # define custom methods here
              end # class
              

              Widget will inherit an each iterator method from it's superclass, as well as an each_with_index method from Enumerable. (..and many other iterator methods, such as all, any, collect, etc.)

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • S Offline
                spireup
                last edited by

                @tig said:

                Paul

                Your syntax seems to be shot to pieces...
                You seem to be mixing up 'if' and 'each' strangely... can you please explain in 'words' what you want to do and what each 'class/method' does... otherwise we are struggling πŸ˜’

                Yes Im miles off!
                What I want to do in words: I have a class called Widget. If there are no Widgets then I want to run a block of code. If there are some Widgets then I want to iterate through them and run a block of code using some or all of each Widgets properties.

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

                  What are these Widget 'properties' ?

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • S Offline
                    spireup
                    last edited by

                    @chris fullmer said:

                    I think this is what you're getting at, translated to ruby syntax, best as I can tell.

                    Hmmm. the .length didnt work. Came back undefined method. At the moment Widget is a bespoke class not like what the guys have suggested below.

                    1 Reply Last reply Reply Quote 0
                    • S Offline
                      spireup
                      last edited by

                      @tig said:

                      What are these Widget 'properties' ?

                      Thanks TIG. Firstly my problem relates to all my classes rather than just one. Ive put Widget is as an example of my problem.

                      However most classes will have x,y,z position info as properties plus a bunch of meta info properties such as :windZone, :snowZone, :saltZone, :quakeZone.

                      Im mulling Dan and Jims suggestion of a subclass but Im not sure how these proeprties would fit into say a hash or an array. I read somewhere by ?thomthom that hashes perform better so Im going to try and work with them once I bend my head around them.

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

                        class Widget
                          attr_accessor( ;x, ;y, ;z, ;length )###etc
                          ### rest of methods
                          ###
                        end
                        

                        will return the instance variables @x, @length etc that will get set inside other class methods etc, in the form Widget.x or Widget.length etc......

                        TIG

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

                          @spireup said:

                          I have a class called Widget. If there are no Widgets then I want to run a block of code. If there are some Widgets then I want to iterate through them and run a block of code using some or all of each Widgets properties.

                          You need two classes:

                          class WidgetSet < Array
                          end # class
                          
                          MyWidgets = WidgetSet.new()
                          
                          class Widget
                            attr_accessor( ;x, ;y, ;z, ;length )###etc
                            def initialize(*args)
                              # args array can be used here to init
                              # attribute values @x, @y, etc.
                              MyWidgets < self # append this instance to set
                            end
                          end #class
                          

                          EDIT: you don't actually needs a custom Array subclass, you could do:
                          MyWidgets = []
                          and just use a normal Array if you don't need to add any custom methods to your Widget collection.

                          I'm not here much anymore.

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

                            BTW.. if you want your Widgets to persist across sessions.. perhaps Components and attached Attribute Dictionary might be a better solution. (You cannot add custom object class instances to a model's entities.)

                            I'm not here much anymore.

                            1 Reply Last reply Reply Quote 0
                            • S Offline
                              spireup
                              last edited by

                              @dan rathbun said:

                              BTW.. if you want your Widgets to persist across sessions.. perhaps Components and attached Attribute Dictionary might be a better solution. (You cannot add custom object class instances to a model's entities.)

                              Ok thats an important point. Yes I would like my widgets to persist. But Im wanting to do a lot of analytics on the components so maybe Im going to need to use attribute dictionaries for working within sketchup but hash based classes for doing the analytics.

                              I guess Im keen to learn each of the methods that has been suggested so I can choose the right one as I get more familiar with them and the project.

                              Could you show me some example code of your earlier suggestion but using Hash as a superclass. Im interested in seeing how the initialize method would look to have say 4 properties xPos, yPos, zPos , type?

                              1 Reply Last reply Reply Quote 0
                              • S Offline
                                spireup
                                last edited by

                                @dan rathbun said:

                                You need two classes:

                                EDIT: you don't actually needs a custom Array subclass, you could do:
                                MyWidgets = []
                                and just use a normal Array if you don't need to add any custom methods to your Widget collection.

                                Yes youre right Dan Ive been reading about Containers at http://www.ruby-doc.org/docs/ProgrammingRuby/ and I see they use two classes Song and SongList in their example.

                                1 Reply Last reply Reply Quote 0
                                • S Offline
                                  spireup
                                  last edited by

                                  @tig said:

                                  class Widget
                                  >   attr_accessor( ;x, ;y, ;z, ;length )###etc
                                  >   ### rest of methods
                                  >   ###
                                  > end
                                  

                                  will return the instance variables @x, @length etc that will get set inside other class methods etc, in the form Widget.x or Widget.length etc......

                                  Thanks TIG. Yes Ive figured out that attr_accessor and was successfully accessing my Classes properties but not in the context of the suggestions of using Arrays or Hashes as super classes.

                                  Dan illustrates this

                                  @dan rathbun said:

                                  class WidgetSet < Array
                                  > end # class
                                  > 
                                  > MyWidgets = WidgetSet.new()
                                  > 
                                  > class Widget
                                  >   attr_accessor( ;x, ;y, ;z, ;length )###etc
                                  >   def initialize(*args)
                                  >     # args array can be used here to init
                                  >     # attribute values @x, @y, etc.
                                  >     MyWidgets < self # append this instance to set
                                  >   end
                                  > end #class
                                  

                                  Now Im just trying to get the syntax right for those inner args arrays. eg(not working)

                                  class WidgetSet < Array
                                  end # class
                                  
                                  class Widget < Hash
                                    
                                    attr_accessor ;arg1, ;xPos, ;yPos, ;zPos, ;height, ;width, ;type
                                  
                                    def initialize(arg1, xPos, yPos, zPos, height, width, type)
                                    
                                      Hash.new["arg1", arg1, "xPos",xPos,"yPos",yPos,"height", height, "width", width,"type", type] 
                                      @arg1 = arg1  ##etc for each arg
                                      MyWidgets < self 
                                    end 
                                  
                                  1 Reply Last reply Reply Quote 0
                                  • Dan RathbunD Offline
                                    Dan Rathbun
                                    last edited by

                                    @spireup said:

                                    Now Im just trying to get the syntax right for those inner args arrays. eg(not working)

                                    class WidgetSet < Array
                                    > end # class
                                    > 
                                    > class Widget < Hash
                                    >   
                                    >   attr_accessor ;arg1, ;xPos, ;yPos, ;zPos, ;height, ;width, ;type
                                    > 
                                    >   def initialize(arg1, xPos, yPos, zPos, height, width, type)
                                    >   
                                    >     Hash.new["arg1", arg1, "xPos",xPos,"yPos",yPos,"height", height, "width", width,"type", type] 
                                    >     @arg1 = arg1  ##etc for each arg
                                    >     MyWidgets < self 
                                    >   end 
                                    

                                    It does you no good to construct an object without a reference to it (the line with Hash.new).

                                    If you want to use a Hash, then use one for your Widgets. They need not be a custom subclass, unless you need custom methods. Hashes dont need attributes (instance refs,) because they use key / value pairs, instead.

                                    my_widget_1 = {
                                      'xPos' => 3.4,
                                      'yPos' => 1.0,
                                      'zPos' => 2.3,
                                      'height' => 6.784,
                                      'width' => 4.0,
                                      'type' => "some_type"
                                    } 
                                    

                                    There is another thread on how to save and retrieve hashes into/from an Attribute dictionary.
                                    see: http://forums.sketchucation.com/viewtopic.php?f=180&t=30066


                                    Arguments: *list_name compacts an argument list into a local array referenced by list_name

                                    Within the method, you can access array elements using the [] method.

                                    def some_method(*args)
                                      @xPos =( args.size>0 ? args[0] ; 0.0 ) 
                                      @yPos =( args.size>1 ? args[1] ; 0.0 ) 
                                      # etc.  
                                    end
                                    

                                    If you use 5 arguments, but a call gives more than 5, the addtional arguments will be still be stored in the local array, and no ArgumentError, will be raised.


                                    I suggest you visit the Code Snippet index:
                                    http://forums.sketchucation.com/viewtopic.php?f=180&t=28846&p=323876#p322175

                                    I'm not here much anymore.

                                    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