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
> #<Object:0x100f9480>
> 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.