WIN32OLE#[] and 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 Suketa

Hi!

Masaki Suketa 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 (*args)
            object.getproperty(name, *args)
        end
        def =(*args)
            object.setproperty(name, *args)
        end
    end
    def (*args)
        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 Suketa!

Cheers,
Dave

Masaki Suketa wrote:

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

  Regards,
  Masaki Suketa

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

Hello,

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 Suketa

···

In message "Re: WIN32OLE# and WIN32OLE#= method in Ruby 1.9 (or later)" on 06/03/25, "Dave Burt" <dave@burt.id.au> writes:

Hi again,

Masaki Suketa wrote:

> 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

···

In message "Re: WIN32OLE# and WIN32OLE#= method in Ruby 1.9 (or > later)" > on 06/03/25, "Dave Burt" <dave@burt.id.au> writes:

Hello,

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 Suketa

···

In message "Re: WIN32OLE# and WIN32OLE#= method in Ruby 1.9 (or later)" on 06/03/27, "Dave Burt" <dave@burt.id.au> writes: