I am writing a small helper to walk a hash or an array of arrays to find a nested key. (by the way, if there is an existing function for this in Ruby I will willingly take it instead). The call is this keywalk(collection, key) the def is this def keywalk(collection,key) key = key.to_s collection.each do |check| return check[1] if check[0] == key keywalk(check,key) if (check.is_a?(Array) or check.is_a?(Hash)) end nil end The problem that I have is that key is always nil inside collection.each even though it is define inside the method and a puts shows that it has the value passed as that parameter. Why is key evidently out of scope inside the iterator? -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Jan 19, 9:54 pm, byrnejb <byrn...-fqAF1SpE7daWxEb2tNKyrg@public.gmane.org> wrote:> The call is this > > keywalk(collection, key) > > the def is this > > def keywalk(collection,key) > key = key.to_s > collection.each do |check| > return check[1] if check[0] == key > keywalk(check,key) if (check.is_a?(Array) or check.is_a?(Hash)) > end > nil > end > > The problem that I have is that key is always nil inside > collection.each even though it is define inside the method and a puts > shows that it has the value passed as that parameter. Why is key > evidently out of scope inside the iterator?blocks can see variables created outside them (but local variables created inside the block do not persist outside it) Your keywalk function will however almost always return nil - when you recurse and call keywalk a second time you are ignoring the return value Fred -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Jan 19, 7:17 pm, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > blocks can see variables created outside them (but local variables > created inside the block do not persist outside it) > Your keywalk function will however almost always return nil - when you > recurse and call keywalk a second time you are ignoring the return > value > > FredOK. Then I am missing something simple. And, I am probably trying too hard. I will revisit the problem. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
I am clearly misunderstanding something fundamental about ruby methods and the return statement. I have finally gone for the blunt force solution so that I can follow along with what is happening. def keywalk(tcoll,tkey,result=nil) if result puts("result returned = #{result}") return result end print tcoll.to_yaml puts("") tcoll.each_pair do | tk, tv | puts("tkey is #{tkey} and tk is: #{tk} and tv is #{tv}") if tk.to_s == tkey.to_s puts("keys are equal and tv is #{tv}") result = { tkey => tv.to_s } puts("The result is = #{result}") return end if tv.kind_of?(Array) puts("Array = #{tv.inspect}") tv.each do |tva| if tva.kind_of?(Hash) keywalk(tva,tkey,result) end end elsif tv.kind_of?(Hash) puts("Hash = #{tv.inspect} class is #{tv.class}") keywalk(tv,tkey,result) else # puts("Something else = #{tv.inspect} with class # {tv.class}") end end puts("The final result was = #{result}") result end Why, even when I finally find the inner key which this does accomplish, do I always get nil returned? What do I misapprehend about returns? tkey is user_id and tk is: user_id and tv is 339 keys are equal and tv is 339 The result is = user_id339 This is what keywalk returns: -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Quoting byrnejb <byrnejb-fqAF1SpE7daWxEb2tNKyrg@public.gmane.org>:> I am clearly misunderstanding something fundamental about ruby methods > and the return statement. > > I have finally gone for the blunt force solution so that I can follow > along with what is happening. > > def keywalk(tcoll,tkey,result=nil) > > if result > puts("result returned = #{result}") > return result > end > > print tcoll.to_yaml > puts("") > > tcoll.each_pair do | tk, tv | > puts("tkey is #{tkey} and tk is: #{tk} and tv is #{tv}") > if tk.to_s == tkey.to_s > puts("keys are equal and tv is #{tv}") > result = { tkey => tv.to_s } > puts("The result is = #{result}") > return > endDo you mean ''return result'' here? Jeffrey -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Exactly right. "return" alone will always return "nil". Aleksey On Jan 21, 9:28 am, "Jeffrey L. Taylor" <r...-f/t7CGFWhwGcvWdFBKKxig@public.gmane.org> wrote:> Quoting byrnejb <byrn...-fqAF1SpE7daWxEb2tNKyrg@public.gmane.org>: > > > > > > > I am clearly misunderstanding something fundamental about ruby methods > > and the return statement. > > > I have finally gone for the blunt force solution so that I can follow > > along with what is happening. > > > def keywalk(tcoll,tkey,result=nil) > > > if result > > puts("result returned = #{result}") > > return result > > end > > > print tcoll.to_yaml > > puts("") > > > tcoll.each_pair do | tk, tv | > > puts("tkey is #{tkey} and tk is: #{tk} and tv is #{tv}") > > if tk.to_s == tkey.to_s > > puts("keys are equal and tv is #{tv}") > > result = { tkey => tv.to_s } > > puts("The result is = #{result}") > > return > > end > > Do you mean ''return result'' here? > > Jeffrey-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Jeffrey L. Taylor wrote:> Quoting byrnejb <byrnejb-fqAF1SpE7daWxEb2tNKyrg@public.gmane.org>: >> return result >> puts("The result is = #{result}") >> return >> end > > Do you mean ''return result'' here?You may also be confused by the ActiveSupport "returning" method.> > JeffreyBest, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Jeffrey L. Taylor wrote:> > end > > Do you mean ''return result'' here? > > JeffreyThank you for pointing out the error with the return. I fixed that and and then finally realised that I was not assigning my return value when calling the method recursively. This was why the result was disappearing after I found it. The final code looks like this: def keywalk(tcoll,tkey,result=nil) tcoll.each_pair do | tk, tv | if tk.to_s == tkey.to_s result = { tkey => tv.to_s } return result if result end if tv.kind_of?(Array) puts("Array = #{tv.inspect}") tv.each do |tva| if tva.kind_of?(Hash) result = keywalk(tva,tkey,result) return result if result end end elsif tv.kind_of?(Hash) puts("Hash = #{tv.inspect} class is #{tv.class}") result = keywalk(tv,tkey,result) return result if result end end return result end A bit bit wordy but at least I can follow along with it in my head. Regards, -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.