Variable problem
-
Please would someone be kind enough to show me how to sort out this snippet?
def kf(time) keyframes = {} model = Sketchup.active_model d = model.attribute_dictionaries['kframes'] d.each_pair do | key,value | a = 1 value.each do | v | if v.nil? v = [[1,0,0],0] end v << time * a a += 1 end keyframes[key] = value end return keyframes end
When I
puts
the v's all are correct, butvalue
returns the previously nil v' s to nil. Just cannot see why!Thanks
-
It doesn't work as you expect because you are not changing the content of the array. You're dealing with a local copy.
I changed your loop to use.map
- that should work. (untested)<span class="syntaxdefault"><br />def kf</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">time</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> keyframes </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{}<br /></span><span class="syntaxdefault"> model </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model<br /> d </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">attribute_dictionaries</span><span class="syntaxkeyword">[</span><span class="syntaxstring">'kframes'</span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault"> d</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_pair do </span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> key</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">value </span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault"> a </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> 1<br /> value</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">map do </span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> v </span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault"> if v</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">nil</span><span class="syntaxkeyword">?<br /></span><span class="syntaxdefault"> v </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[[</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">],</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault"> end<br /> v </span><span class="syntaxkeyword"><<</span><span class="syntaxdefault"> time </span><span class="syntaxkeyword">*</span><span class="syntaxdefault"> a<br /> a </span><span class="syntaxkeyword">+=</span><span class="syntaxdefault"> 1<br /> v<br /> end<br /> keyframes</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">key</span><span class="syntaxkeyword">]</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> value<br /> end<br /> return keyframes<br />end<br /></span>
-
@thomthom said:
It doesn't work as you expect because you are not changing the content of the array. ....
Thanks but I am sorry to say it doesn't work at all.
Also my original code successfully adds the time to each (
v
) array, it only seems the nil block is being ignored byvalue
.So I don't know ...
-
.... but
map
does work if there aren't any nil elements in thevalue
arrays. -
@chrisglasier said:
Thanks but I am sorry to say it doesn't work at all.
sorry, should be
.map!
@chrisglasier said:
Also my original code successfully adds the time to each (v) array, it only seems the nil block is being ignored by value.
Yes, because
nil
is immutable. -
value.each do | v | if v.nil? v = [[1,0,0],0] end v << time * a a += 1 end keyframes[key] = value end
looks through the contents of 'value' and assigns some values to elements in array 'v', then it sets the keyframes[key] back to be value ???
Don't you want to modify 'key'?
Why don't you usekeyframes[key] = v
??? -
@tig said:
value.each do | v | > if v.nil? > v = [[1,0,0],0] > end > v << time * a > a += 1 > end > keyframes[key] = value > end
looks through the contents of 'value' and assigns some values to elements in array 'v', then it sets the keyframes[key] back to be value ???
Don't you want to modify 'key'?
Why don't you usekeyframes[key] = v
???Value is an array of arrays (like [[1,0,0],0]). So v is one of those. I am sure it is caused by the nil block? (immutable??). Perhaps I should make a new array from the
v
's because they are OK.I will try that later or tomorrow.
Thanks for your help.
-
In which case
... new_value = [] value.each do | v | if v ### ??? ### isn't this what you want ?*** v << time * a else ### OR it's nil v = [[1,0,0],0] end ### ***if NOT then revert to your format... new_value << v a += 1 end keyframes[key] = new_value end
-
@tig said:
In which case
... > new_value = [] > value.each do | v | > if v ### ??? ### isn't this what you want ?*** > v << time * a > else ### OR it's nil > v = [[1,0,0],0] > end ### ***if NOT then revert to your format... > new_value << v > a += 1 > end > keyframes[key] = new_value > end >
Yes that looks good;I guess I can use
v.is_a?(Array)
for the if bit as the nil candidates are just empty elements.Thanks to you both ...
-
if v
returnstrue
ifv
is notnil
or not[]
The else then takes it's 'converse' i.e. it isnil
OR[]
I'm not clear about how a good or bad entry for 'value >>> v' might actually 'look' in your code... -
@tig said:
I'm not clear about how a good or bad entry for 'value >>> v' might actually 'look' in your code...
<span class="syntaxdefault">new_value </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[]<br /></span><span class="syntaxdefault"> value</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each do</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> v </span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault"> if </span><span class="syntaxkeyword">!</span><span class="syntaxdefault">v</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">is_a</span><span class="syntaxkeyword">?(Array)<br /></span><span class="syntaxdefault"> v </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[[</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">],</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault"> end<br /> v </span><span class="syntaxkeyword"><<</span><span class="syntaxdefault"> time </span><span class="syntaxkeyword">*</span><span class="syntaxdefault"> a<br /> a </span><span class="syntaxkeyword">+=</span><span class="syntaxdefault"> 1<br /> new_value </span><span class="syntaxkeyword"><<</span><span class="syntaxdefault"> v<br /> end<br /> keyframes</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">key</span><span class="syntaxkeyword">]</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> new_value</span>
I did it like this in the end as both types of
v
have time added. Anyway it works which is good! Thanks again.The empty elements currently are needed to delay certain rotations - like a kick at the end of a run. I have a mechanism to modularise the animation. I want to leave that until later.
Advertisement