Win32OLE bug

I’m seeing the following in 1.8.0 (mswin32) using win32ole:

In this case, i am working with Internet Explorer. $iec.document is the
WIN32OLE wrapper around the document object (ie. the DOM).

Also, one of the forms in this DOM has an action == “start”.

irb(main):009:0> for form in $iec.document.forms
irb(main):010:1> if form.action == "start"
irb(main):011:2> return form
irb(main):012:2> end
irb(main):013:1> end
LocalJumpError: unexpected return
from (irb):11
from (irb):9:in `each’
from (irb):9

Note: this behavior is better than in 1.6.8. In that case, the function
appeared to work correctly, but then ruby would hang on exit. That was a
bear to isolate!

I’m not sure if this is a known problem, or how to go about reporting it.
Any suggestions?

(P.S. I do know how to workaround this bug:

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

)

Bret

···

Bret Pettichord, Software Tester
Book - www.testinglessons.com
Consulting - www.pettichord.com
Blog - www.io.com/~wazmo/blog

Homebrew Automation Seminar
March 19, Redmond, Washington
www.sasqag.org/99days/#automation

I don’t know much about win32ole extension, but LocalJumpError has
nothing to do with the extension, but more with how “return” operation
works in Ruby. For example,

$ ruby -v
ruby 1.9.0 (2004-03-10) [powerpc-darwin]
$ irb
irb(main):001:0> (1…10).each{return}
LocalJumpError: return from proc-closure
from (irb):1
from (irb):1:in `each’
from (irb):1

The thing is that in this case the context of the ‘return’ has passed
already.
For details check out this discussion:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/2583

I’m seeing the following in 1.8.0 (mswin32) using win32ole:

irb(main):009:0> for form in $iec.document.forms
irb(main):010:1> if form.action == “start”
irb(main):011:2> return form
irb(main):012:2> end
irb(main):013:1> end
LocalJumpError: unexpected return
from (irb):11
from (irb):9:in `each’
from (irb):9

Cheers,
Kent.

···

On Mar 11, 2004, at 7:19 PM, Bret Pettichord wrote:

Bret,

There are probably better ways to do this that I would think of if I 

weren’t so tired, but this one will get you around the JumpError
problem.

form = callcc do |cc|
ie.document.forms.each do |form|
if(form.action == “start”)
cc.call(form)
end
end
end

puts form.inspect
“#<WIN32OLE:0x28bcf48”

Chad

···

On Thursday, March 11, 2004, at 09:02 PM, Kent Sibilev wrote:

On Mar 11, 2004, at 7:19 PM, Bret Pettichord wrote:

I don’t know much about win32ole extension, but LocalJumpError has
nothing to do with the extension, but more with how “return” operation
works in Ruby. For example,

$ ruby -v
ruby 1.9.0 (2004-03-10) [powerpc-darwin]
$ irb
irb(main):001:0> (1…10).each{return}
LocalJumpError: return from proc-closure
from (irb):1
from (irb):1:in `each’
from (irb):1

The thing is that in this case the context of the ‘return’ has passed
already.
For details check out this discussion:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/2583

I’m seeing the following in 1.8.0 (mswin32) using win32ole:

irb(main):009:0> for form in $iec.document.forms
irb(main):010:1> if form.action == “start”
irb(main):011:2> return form
irb(main):012:2> end
irb(main):013:1> end
LocalJumpError: unexpected return
from (irb):11
from (irb):9:in `each’
from (irb):9

I don’t know much about win32ole extension, but LocalJumpError has
nothing to do with the extension, but more with how “return” operation
works in Ruby. For example,

$ ruby -v
ruby 1.9.0 (2004-03-10) [powerpc-darwin]
$ irb
irb(main):001:0> (1…10).each{return}
LocalJumpError: return from proc-closure
from (irb):1
from (irb):1:in `each’
from (irb):1

Kent, thanks. This helps me see that the behavior i’m seeing is not a
consequence of win32ole.

The thing is that in this case the context of the ‘return’ has passed
already.
For details check out this discussion:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/2583

I’m sorry, but i’m too dumb to understand this. Instead, i made some
experiments, which i repeat below.

I’m seeing the following in 1.8.0 (mswin32) using win32ole:

irb(main):009:0> for form in $iec.document.forms
irb(main):010:1> if form.action == “start”
irb(main):011:2> return form
irb(main):012:2> end
irb(main):013:1> end
LocalJumpError: unexpected return
from (irb):11
from (irb):9:in `each’
from (irb):9

Bret,

There are probably better ways to do this that I would think of if I
weren’t so tired, but this one will get you around the JumpError problem.

form = callcc do |cc|
ie.document.forms.each do |form|
if(form.action == “start”)
cc.call(form)
end
end
end

puts form.inspect
“#<WIN32OLE:0x28bcf48”

Chad

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

···

At 10:12 PM 3/11/2004, Chad Fowler wrote:

On Thursday, March 11, 2004, at 09:02 PM, Kent Sibilev wrote:

On Mar 11, 2004, at 7:19 PM, Bret Pettichord wrote:


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

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.

>

>form = callcc do |cc| #1

> ie.document.forms.each do |form| #2

> if(form.action == “start”) #3

> cc.call(form) #4

> end #5

> end #6

>end #7

>

>puts form.inspect

>"#<WIN32OLE:0x28bcf48"

>

>

>Chad

···

On Sat, 13 Mar 2004, 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.

Line one of my example assigns the result of the #callcc invocation to the
"form" variable. callcc stands for “call with current continuation”. The
continuation (to simplify) is a complete snapshot of state at a current
point in time (including the position of execution). Executing the #call
method on the continuation returns to the point directly after the #callcc
invocation, unwinding the call stack, and any arguments passed into #call
(such as “form” in line 4) are the return values from the #callcc
invocation itself.

Jim Weirch has a much more lucid explanation here:
http://onestepback.org/index.cgi/Tech/Programming/Kata/KataTwoCallCC.rdoc

Alternatively, for this example, you could use throw and catch.

Chad