Correlative name of variables

I have a class like this:

class MyClass
  attr_accessor :cust_id, :cust_name, :cust_addr
  @@no_of_lines = 0
   def initialize(id, name, addr)
      @cust_id = id.to_s
      @cust_name = name
      @cust_addr = addr
      @cust_serial = @@no_of_lines
      @@no_of_lines += 1

Suppose I want to insert all of my objects inside an array “a”

a = []
lin1 ="id1","Name1","Adrr1")
lin2 ="id2","Name2","Adrr2")
lin3 ="id3","Name3","Adrr3")

How can assign variable names “lin1, lin2, lin3” correlative by @@no_of_lines instead of naming each one. My aim is to store the array “a” in the model.attribute_dictionaries but avoiding to name each variable.

Are you creating the array all at once as your snippet shows ?

ie, you could just do …

a = ["id1","Name1","Adrr1"),"id2","Name2","Adrr2"),"id3","Name3","Adrr3")

… or …

a = { |i|
  n = i + 1"id#{n}", "Name#{n}", "Adrr#{n}") 

I started with that code but I’m not able to store “a” variable inside an attribute dictionary, the value seems to be an array but it shows as [,] and there is nothing inside.
Is it possible to store the instances I create with"id1","Name1","Adrr1") inside the model?

This is a small test I did (without module yet)

@model = Sketchup.active_model
@Data_dict = @model.attribute_dictionary('Data',true)
@detail = @Data_dict.attribute_dictionary('Detail',true)

class MyClass
  attr_accessor :cust_id, :cust_name, :cust_addr
  @@no_of_lines = 0
  def initialize(id, name, addr)
    @cust_id = id.to_s
    @cust_name = name
    @cust_addr = addr
    @cust_serial = @@no_of_lines
    @@no_of_lines += 1

#Read existing data
if @detail['detailedData']
  @a = @detail['detailedData']
  @a = []
  @Data_dict .set_attribute('Detail','detailedData',@a)

#New data

#Save new data inside model
@Data_dict .set_attribute('Detail','detailedData',@a)

But there is nothing inside my attribute_dictionary

Oh, yea. The AttributeDictionary class is only aware of certain data classes and API classes, so it cannot store what it does not know (which means your custom class.)

So if you have just some text that you wish to store, I suggest using a Hash which is the most alike of core classes with AttributeDictionary.

Since the API’s AttributeDictionary class has Enumerable library mixed in, it inherits a #to_h method that can convert the dictionary to a hash object.

h = dict.to_h

To go the other way and store a hash into a dictionary use:

h.each do |key, value|
  dict[key.to_s]= value

Also, I think dictionary keys must be strings not symbols.


See the info on the Sketchup::AttributeDictionary[]= method.

It states that the allowed values can be any of the following:

Boolean , Integer , Float , Length, nil , String, Time , Array, Geom::Point3d, Geom::Vector3d

It doesn’t make clear what elements the array can contain, but one might assume that they must come from the same list. Hence, they cannot contain a class instance, which is what generates.

A model file should be able to be opened by SketchUp installed on any pc. If user defined classes/objects were allowed as values in AttributeDictionaries, the model would lose data unless the system had a definition of the object available…

So, you need some way to serialize your MyClass objects into a string ot an array of strings…

FYI, the top level attribute space, for the model or any entity, is a shared space.
This means that extensions must use unique top level dictionary names to prevent clashing between extensions.
It is common for an extension to prefix it’s name with the author’s namespace + “_” + extension submodule.
This is often used for the extension’s options key anyway.

I keep seeing this in your snippet:

  @Data_dict .set_attribute('Detail','detailedData',@a)

There should not be a space between the object reference and the dot method call.

So you want to have a data class.

Ruby has two choices:

… or use a custom solution:

Just my luck!. Thanks to both @DanRathbun and @MSP_Greg . I thought it will be more efficient than hash.
It actually makes sense to avoid storing data that may not be read by other users. I thought the class structure was somehow stored with the data.
I started with hash at the begining and it was possible to have correlative name of keys “as strings”
This was tha way I did it.

  orderString = "m"+"%06d"%order 
  "m#{ordenString}" = {
    cust_id : id
    cust_name : name
    cust_addr : addr
  order +=1

There are many of syntax, as well as “theoretical” mistakes…

  • the order variable is not defined at the beginning. (e.g.: order = 1)
  • the orderString already contains the “m” at a first row, so I do not see a reason to add an other “m” in "m#{ordenString}" (also it should be “m#{orderString}”
  • yuo can not use a string ( "m#{orderString}" ) as a variable name

the assigned hash syntax is wrong:

  • comma are missing between elements
  • between a hash key and colon should not have space
    (the value variables are also not defined here)

At least statically this will be okay :

order = 1
order_hash = {}
orderString = "m"+"%06d"%order 
order_hash[orderString] = {
  cust_id: "id1",
  cust_name: "name1",
  cust_addr: "addr1"
1 Like

You are right, it’s only an example from my long code and trasnlated to english because most of my variables are spanish words, so I din’t copy my commas. In this case I need two “m”, the secons one means “manual” and order is declared at the begining of muy code.
In this case ( "m#{orderString}" ) is the key of a hash value.

Sorry for the misunderstanding @dezmo and for mixing topics .

For attribute dictionaries, it is the other way around. The data is stored with the instance object (so to speak.)
In actuality, the data may be in special section(s) of the file with the object as the key.