[Info] Allowable Classes for "set_attribute"
-
Unless your Hash string includes quotes, in which case you need to escape those first.
-
@jim said:
Unless your Hash string includes quotes, in which case you need to escape those first.
NOPE.. Ruby does it for you.
` hashStr = %( {"Stature"=>5.5, "Name"=>"Dan", "FavFoods"=>["Mac and Cheese", "SpiceCake", "Coffee"], "Age"=>49})
hashStr.inspect
" {"Stature"=>5.5, "Name"=>"Dan", "FavFoods"=>["Mac and Cheese", "SpiceCake", "Coffee"], "Age"=>49}"
my_hash = eval(hashStr)
{"Stature"=>5.5, "Name"=>"Dan", "FavFoods"=>["Mac and Cheese", "SpiceCake", "Coffee"], "Age"=>49}
my_hash.class
Hash`
-
Huh, I thought I had problems with that in the past.
-
@jim said:
Huh, I thought I had problems with that in the past.
Could be.
-
Might have been using Ruby 1.8.0* Might have been conflicts between PC (1.8.0) and Mac (1.8.5)* I imagine you could confuse Ruby with poor use of delimiters, or maybe embedded newlines?
I would always recommend using .inspect to build the string, as it: -
Correctly knows how to iterate the hash, and any nested structures inside it, like nested arrays, nested hashes, etc.* For objects that it does not know how to 'convert' it will make an 'info string': "#Sketchup::Face:0x3F56D20A" (or similar)* Uses the same delimiters (double quotes,) for all strings and hash keys (which allows the use of a single quote for possesion apostrophe. ie: "Dan's idea!"
-
-
@kwalkerman said:
Be careful with hash, because if you have an array, and one of the array values is a hash, it will return the array, but instead of returning the hash, it will return nil.
See the post directly above.
The "tip" on using .inspect (to build the attribute strings,) for hashes, goes also for arrays.
The .inspect method will convert hashes nested inside arrays, and arrays nested inside hashes, etc. Multiple levels deep as well. -
Dan,
Very nice. I will definitely use this. Too bad it's not embedded in SU though.
Jim - I have found that any sub-components of arrays also need to be one of the allowable classes.
Thom - trueclass and falseclass also work. I'm updating the first post accordingly.
--
Karen -
VERY useful thread, thanks !
Please make it kind of sticky: I've been chasing an uncatchable bug for hours, ignoring this information... Others might like to know this in the future! -
To recover a hash-string from an attribute, you eval() it into a reference.
hashStr = some_entity.get_attribute( "dict_name", "hash_att" ) my_hash = eval(hashStr)
-
Length
classes also seem to be stored and recovered properly. I'd thought that maybe it got read back asFloat
, but in my tests I seem to getLength
- anyone confirm? -
@kwalkerman said:
Array -- good to store by doing "array.inspect" first, see Dan's comments below
Only if the array contains hashes. If the array only use the other allowable types there is no need. Might be less overhead since it's not parsing between strings.
-
Geom::Point3d
also seems to be possible to store:
` pt1=Geom::Point3d.new(1,2,3)
Point3d(1, 2, 3)
pt2=Geom::Point3d.new(4,5,6)
Point3d(4, 5, 6)
pt3=Geom::Point3d.new(7,8,9)
Point3d(7, 8, 9)pt_array = [ pt1, pt2, pt3 ]
[Point3d(1, 2, 3), Point3d(4, 5, 6), Point3d(7, 8, 9)]model.set_attribute('test', 'bar', pt_array )
[Point3d(1, 2, 3), Point3d(4, 5, 6), Point3d(7, 8, 9)]model.get_attribute('test', 'bar' )
[Point3d(1, 2, 3), Point3d(4, 5, 6), Point3d(7, 8, 9)]`
I even saved the model and reopened it just to make sure it worked across sessions.
-
Although storing/reading-back a 'point3d' or a 'vector3d' as an array [.to_a] would be 'safer' ?
Presumably a 'transformation' is not storeable unless it's first made into an array ? -
@tig said:
Although storing/reading-back a 'point3d' or a 'vector3d' as an array [.to_a] would be 'safer' ?
I was storing points as arrays - because I just assumed point3d's would not work. But they appear to do so. In which case I'd prefer to do so unless there is any known issues.
-
Nice. I just tested it as well. I'll add it to the list.
It also seems to work as an attribute dictionary key:
p1 = Geom::Point3d.new(1,2,3)
p2 = Geom::Point3d.new(4,5,6)entity.set_attribute "k", p1, p2
--
Karen -
@kwalkerman said:
It also seems to work as an attribute dictionary key:
hmm... interesting.
I a haven't tried, but I'd think that
Vector3d
should work as well. (Though one can never be sure until it's tested...) -
yep, vectors work too. I wonder about the other Geom classes (although transformation doesn't work, I just tried it).
--
Karen -
reminder.. that keys should be unique, in the same way that hash keys need to be unique.
If you have two Point3d objects that are
eql?
(in the Ruby sense,) ie, the 3 elements, x, y, z have the same values, (but differingobject_id
,) can they be used as separate keys for 2 separate values ?.. or will one overwrite the other's value in the dictionary ?
-
Dan,
Good point. A quick check indicates that any point with the same x,y, and z values can access the attribute.
--
Karen -
@kwalkerman said:
Good point. A quick check indicates that any point with the same x,y, and z values can access the attribute.
Karen
.. thot so.
This could be bad,.. or good, depending on what your doing. If you wanted to store some explanitory text for ANY point with certain x,y,z co-ordinates like "at the hinge point" then this feature might work ok. (Of course, nil will be returned if no such "point-key" exists in the dictionary.)
-
Dan,
For applications I can think of, this is actually an advantage, especially if you are using attributes between sessions, as the 'entity' attached to your particular point3d would be lost. AND, it works just like any other key for attributes.
string1 = "My Attribute"
string2 = "My Attribute"entity.set_attribute "a", string1, "q"
entity.get_attribute "a", string2 ==> "q"string1 and string2 are different objects, but both can reference the same attribute dictionary.
--
Karen
Advertisement