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 endWhen I
putsthe v's all are correct, butvaluereturns 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
mapdoes work if there aren't any nil elements in thevaluearrays. -
@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
nilis immutable. -
value.each do | v | if v.nil? v = [[1,0,0],0] end v << time * a a += 1 end keyframes[key] = value endlooks 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 > endlooks 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 vreturnstrueifvis notnilor not[]
The else then takes it's 'converse' i.e. it isnilOR[]
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
vhave 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