From: Kent Sibilev Date: 2004-03-13T04:48:40+09:00 Subject: Re: Win32OLE bug Yes, it seems that WIN32OLE library doesn't mix-in Enumerable module into its collections. This would work: forms = $iec.document.forms forms.extend(Enumerable) forms.find{|f| f.action == 'start'} According to PickAxe http://rubycentral.com/book/tut_expressions.html#UK the only difference between 'for..in' and 'each' forms of iteration is the scope of local variables defined in the iteration block. /kent. On Mar 12, 2004, at 1:58 PM, Bret Pettichord wrote: > Thanks Chad. I actually included my workaround in my original post > (but which kent snipped). I don't understand what you have here. > Here's my original workaround: > > def get_form_by_action(action) > "Return the first Form on the current page that has the specified > Action." > retval = nil # this ugliness avoids scripts hanging on exit (1.6) or > a LocalJumpError (1.8) > for form in @iec.document.forms > next if retval > if form.action == action > retval = IEDomFormWrapper.new(form) > end > end > return retval > end > > > Here is what i really want to do: > > irb(main):036:0> $iec.document.forms.find {|f| f.action == "start" } > WIN32OLERuntimeError: Unknown property or method : `find' > HRESULT error code:0x80020006 > Unknown name > from (irb):36:in `method_missing' > from (irb):36 > from ?:0 > > forms is an OLE collection object, so it supports each, but apparently > doesn't have Enumerable mixed in. Can i mix this in on my own? Should > i be expecting this to be done by the WIN32OLE library? > > Here's my latest rewrite, which works, and is easier for me to > understand and explain than the one you gave Chad. (I don't know what > callcc does. Continuations? I'll leave that for another day.) > > def get_form_by_action(action) > "Return the first Form on the current page that has the specified > Action." > for form in @iec.document.forms > break if form.action == action > end > IEDomFormWrapper.new(form) > end > > I did try the following, but was surprised to see that it didn't work, > since i thought that this was supposed to be the same as the previous > but more the ruby way. > > def get_form_by_action(action) > "Return the first Form on the current page that has the specified > Action." > @iec.document.forms.each do | form | > break if form.action == action > end > IEDomFormWrapper.new(form) > end > > This give this error: > > irb(main):044:0> get_form_by_action("start") > NameError: undefined local variable or method `form' for > # > from ./toolkit/iec-assist.rb:39:in `get_form_by_action' > from (irb):44 > from ./toolkit/iec-assist.rb:2 > > To correct, i need to explicitly change the scope of the bound > variable: > > def get_form_by_action(action) > "Return the first Form on the current page that has the specified > Action." > form = nil > @iec.document.forms.each do | form | > break if form.action == action > end > IEDomFormWrapper.new(form) > end > > As you may know i am preparing to teach novices to use Ruby, and i > can't quite think of how i can teach them why these two forms are > different. It would be much easier for me to be able to say they are > the same. (Between you and me, i see that the scope of the bound > variable is different between the for-in and each forms. But this > means that the difference is more than just syntactic sugar.) > > So, am i still confused somewhere? Is it supposed to be this way? (I'm > using 1.8.0.) > > Is there a way i can get forms.find to work directly? > > Bret > > ______________________________________ > Bret Pettichord, Software Tester > Consultant - www.pettichord.com > Author - www.testinglessons.com > Blogger - www.io.com/~wazmo/blog > > Homebrew Automation Seminars > March 19, Redmond, Washington > April 30, Austin, Texas > www.pettichord.com/training.html > > Cheers, Kent.