WIN32OLE#= method in Ruby 1.9 (or later)

Hello,

I have a question about Win32OLE.
I think that I’ll change the behavior of WIN32OLE#[] and WIN32OLE#[]=
in Ruby 1.9 or later.

I have not commited the change yet.
Before commiting it, I want suggestions or opinions from Win32OLE users.

For example,
excel = WIN32OLE.excel(“Excel.Application”)
excel[“Visible”] = true
is NG.
Instead, You must write
excel = WIN32OLE.excel(“Excel.Application”)
excel.Visible = true

For more,
installer = WIN32OLE.new(“WindowsInstaller.Installer”)
record = installer.CreateRecord(2)
record [“StringData”, 1] = ‘dddd’

is NG. Instead,
installer = WIN32OLE.new(“WindowsInstaller.Installer”)
record = installer.CreateRecord(2)
record.setproperty(“StringData”, 1, ‘dddd’)

By using new featuer, You can write

worksheet.cells[1,2] = 10

in Excel.

For more, you can write

WIN32OLE.new(“WScript.Shell”)
env = sh.Environment(“User”)
p env[“FOO”]
env[“FOO”] = “BARBAZ”

For more, you can write

ado = WIN32OLE.new(“ADODB.Connection”)
ado.Open("…")
rs = ado.Execute(“SELECT * from TABLE01”)
while !rs.EOF
puts rs.Fields.Item(“id”).value
puts rs.Fields(“id”).value
puts rs[“id”].value # This is new feature!
rs.MoveNext
end

and so on. Any comment, any question, welcome.

Regards,
Masaki S.

Hi!

Masaki S. wrote:

I have a question about Win32OLE.
I think that I’ll change the behavior of WIN32OLE#[] and WIN32OLE#[]=
in Ruby 1.9 or later.

I have not commited the change yet.
Before commiting it, I want suggestions or opinions from Win32OLE users.

No longer allowed:

excel[“Visible”] = true
record [“StringData”, 1] = ‘dddd’

New:

worksheet.cells[1,2] = 10
env[“FOO”] = “BARBAZ”
puts rs[“id”].value # This is new feature!

Excellent! This makes a lot more sense than the existing function of []
and
[]=.

When I first used WIN32OLE, I was surprised that you couldn’t use [] to
access index operations.

I haven’t used obj[prop, n] before, that I can recall. I think neither
that
nor setproperty() are the ideal Ruby syntax for this operation, but []
seems
better. How about this:

record [“StringData”, 1] = ‘dddd’
record.setproperty(“StringData”, 1, ‘dddd’)

record[:StringData][1] = ‘dddd’

Possible implementation:
class WIN32OLE
class Property
attr_reader :object, :name
def initialize(obj, name)
unless obj.kind_of?(WIN32OLE)
raise TypeError.new(“cannot convert #{obj.inspect} to
WIN32OLE”)
end
self.object = obj
self.name = name.to_s
end
def
object.getproperty(name, *args)
end
def []=(*args)
object.setproperty(name, *args)
end
end
def
if args.size == 1 && args[0].kind_of?(Symbol)
return Property.new(self, *args)
end
# everything else
end
end

(I realize there’s ‘win32ole/property’ already, but I don’t know exactly
what its purpose is.)

Thanks a lot for WIN32OLE, Masaki S.!

Cheers,
Dave

Masaki S. wrote:

and so on. Any comment, any question, welcome.

Regards,
Masaki S.

I have been using WIN32OLE like this:

def test_get_serial
bios = WIN32OLE.connect(“winmgmts:\\.”)
bios.InstancesOf(“win32_bios”).each do |item|
return item.serialnumber
end
end

Thank you.
Brad

Hi again,

Masaki S. wrote:

In message “Re: WIN32OLE#[] and WIN32OLE#[]= method in Ruby 1.9 (or
later)”
on 06/03/25, “Dave B.” [email protected] writes:

record.setproperty(“StringData”, 1, ‘dddd’)

record[:StringData][1] = ‘dddd’

Thank you. It is very interesting.
I think about it.

It’s not ideal, but WIN32OLE doesn’t use Symbols - VBScript and JScript
don’t have them.
We’re trying to match this VBScript, right?

record.StringData(1) = “dddd”

As far as I understand, we can’t make record.StringData(1) = “dddd” or
record.StringData[1] = “dddd” work while keeping the same dynamic call
functionality we already have (StringData should be called as a method
in
both cases) but what about another option:

record.StringData{1} = “dddd”

The rule would be similar to the above, but instead of looking for a
symbol,
you’re looking for block_given? and using “yield” as the index/parameter
to
the property.
Although, in a sense, this matches semantic-for-semantic less than the
[:StringData] version, and that’s what I like best about the change
you’re
suggesting - use Ruby’s index operators for the same purpose in OLE.

Thanks again for your efforts on this project,
Dave

Hello,

In message “Re: WIN32OLE#[] and WIN32OLE#[]= method in Ruby 1.9 (or
later)”
on 06/03/25, “Dave B.” [email protected] writes:

I haven’t used obj[prop, n] before, that I can recall. I think neither that
nor setproperty() are the ideal Ruby syntax for this operation, but [] seems
better. How about this:

record [“StringData”, 1] = ‘dddd’
record.setproperty(“StringData”, 1, ‘dddd’)

record[:StringData][1] = ‘dddd’

Thank you. It is very interesting.
I think about it.

(I realize there’s ‘win32ole/property’ already, but I don’t know exactly
what its purpose is.)

It is helper class of early binding of WIN32OLE.
For example,
ext/win32ole/sample/olegen.rb uses it.
And,
ruby olegen.rb ‘Microsoft ActiveX Data Object N.N Library’
creates some property which uses OLEProperty.

Yes, it is not so convenient.

Regards,
Masaki S.

Hello,

In message “Re: WIN32OLE#[] and WIN32OLE#[]= method in Ruby 1.9 (or
later)”
on 06/03/27, “Dave B.” [email protected] writes:

It’s not ideal, but WIN32OLE doesn’t use Symbols - VBScript and JScript
don’t have them.
We’re trying to match this VBScript, right?

record.StringData(1) = “dddd”

Yes.

As far as I understand, we can’t make record.StringData(1) = “dddd” or
record.StringData[1] = “dddd” work while keeping the same dynamic call
functionality we already have (StringData should be called as a method in
both cases) but what about another option:

I commited the new feature, and I uses the trick (thanks to your hint).
And
record.StringData[1] = “dddd”
works.

But the trick may create another trouble… I am not sure.
So, if the trick does not work fine in another situation, then
I think about using your following suggestion.

record.StringData{1} = “dddd”

The rule would be similar to the above, but instead of looking for a symbol,
you’re looking for block_given? and using “yield” as the index/parameter to
the property.
Although, in a sense, this matches semantic-for-semantic less than the
[:StringData] version, and that’s what I like best about the change you’re
suggesting - use Ruby’s index operators for the same purpose in OLE.

Thanks your great idea!

Regards,
Masaki S.