Overriding CLS Virtuals

I’ve committed some changes to IronRuby (in SVN revision 141) that let
you implement CLS interfaces and override virtual methods on CLS base
types. Interfaces work like Ruby modules, so to make your class
implement IDisposable you could say

require ‘mscorlib’
class Disposable
include System.IDisposable
def Dispose
# Do something
end
end

You can also override virtual properties. A class or interface that has
the C# declaration “string Value { get; set; }” is overridden from
IronRuby with methods named “Value” for the getter and “Value=” for the
setter.

Note that you need to use the same casing as the CLS definition for both
methods and properties.

We’re just getting started with better .NET interop support and don’t
have very much test coverage yet - but this should let you get going on
some more sophisticated interop scenarios than were previously possible.

Oops… that should have said “include System::IDisposable”. My
Outlook-based syntax checker is clearly not working.

From: [email protected]
[mailto:[email protected]] On Behalf Of Curt
Hagenlocher
Sent: Monday, September 08, 2008 9:22 PM
To: [email protected]
Subject: [Ironruby-core] Overriding CLS Virtuals

I’ve committed some changes to IronRuby (in SVN revision 141) that let
you implement CLS interfaces and override virtual methods on CLS base
types. Interfaces work like Ruby modules, so to make your class
implement IDisposable you could say

require ‘mscorlib’
class Disposable
include System.IDisposable
def Dispose
# Do something
end
end

You can also override virtual properties. A class or interface that has
the C# declaration “string Value { get; set; }” is overridden from
IronRuby with methods named “Value” for the getter and “Value=” for the
setter.

Note that you need to use the same casing as the CLS definition for both
methods and properties.

We’re just getting started with better .NET interop support and don’t
have very much test coverage yet - but this should let you get going on
some more sophisticated interop scenarios than were previously possible.


Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core

It’s not real unless you start singing “You are the wind beneath my
wings”.
:slight_smile:

On Mon, Sep 8, 2008 at 9:36 PM, Orion E.


Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core


Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core

Are we planning on supporting name mangling to give more Ruby-ish names?
Like will we be able to do “def dispose” instead of “def Dispose”?

JD


From: [email protected]
[[email protected]] On Behalf Of Brad W.
[[email protected]]
Sent: Monday, September 08, 2008 9:39 PM
To: [email protected]
Subject: Re: [Ironruby-core] Overriding CLS Virtuals

It’s not real unless you start singing “You are the wind beneath my
wings”. :slight_smile:

On Mon, Sep 8, 2008 at 9:36 PM, Orion E.
<[email protected]mailto:[email protected]> wrote:
You are my hero :slight_smile:

Curt H. wrote:

I’ve committed some changes to IronRuby (in SVN revision 141) that let
you implement CLS interfaces and override virtual methods on CLS base
types. Interfaces work like Ruby modules, so to make your class
implement IDisposable you could say

Yes, this has been reported before (in fact, I think it was when someone
was writing “using” ☺) and we haven’t yet worked out a resolution. I’ll
see if there’s something quick that can be fixed here later today.

From: [email protected]
[mailto:[email protected]] On Behalf Of Orion E.
Sent: Monday, September 08, 2008 10:12 PM
To: [email protected]
Subject: Re: [Ironruby-core] Mysteriously broken calls to dispose?

Follow-up

If I call $fs.dispose(true), then it works.

It seems there’s a protected dispose(bool) in a derived class.
I can’t actually call Dispose(true) from C# as the compiler tells me
it’s protected.

It strikes me as somewhat broken that the method which ironruby actually
invokes is the one that you shouldn’t invoke…

At any rate, I’d be overjoyed if anyone could point me in the direction
of a fix. I’m trying to write ‘using’ (a la C#) in ruby as part of demo
for my local .NET user group. It should be trivial and showcase how
awesome IronRuby is :frowning:

Orion E. wrote:
I don’t seem to be able to call Dispose on a filestream. Needless to say
this is problematic.

Here’s a paste, straight from the IR console (latest svn version 141)

require ‘mscorlib’

=> true

include System::IO

=> Object

$fs = FileStream.new( ‘file.txt’, FileMode.Open )

=> #System::IO::FileStream:0x000005c

$fs.Dispose

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\matchcaller.generated.cs:30:in
Call2': wrong number or type of arguments for Dispose’ (ArgumentError)

    from 

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\callsite.cs:275:in
`UpdateAndExecute’

    from 

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\updatedelegates.generated.cs:38:in
`Update2’

    from :0

All the other methods on the filestream object work fine (read_all_text,
and so on), but the call to dispose crashes.

Likewise, I get a crash calling methods with overloads, which looks like
it may (??) be related.

require ‘mscorlib’

=> true

include System::IO

=> Object

$bytes = System::IO::File.read_all_bytes( ‘file.txt’ ); nil # nil is to prevent ir from printing the GIANT ARRAY

=> nil

$text = System::Text::Encoding.UTF8.get_string($bytes)

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\matchcaller.generated.cs:35:in
Call3': wrong number or type of arguments for get_string’
(ArgumentError)

    from 

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\callsite.cs:275:in
`UpdateAndExecute’

    from 

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\updatedelegates.generated.cs:45:in
`Update3’

    from :0

$text = System::Text::Encoding.UTF8.get_string($bytes, 0, $bytes.length)

=> “PROPER TEXT GOES HERE”

It seems like it can’t figure out that there is GetString(bytes) and
GetString(bytes, index, length) and just uses the latter always.
Is there a solution for either of these problems?

Thanks a lot, Orion



Ironruby-core mailing list

[email protected]mailto:[email protected]

http://rubyforge.org/mailman/listinfo/ironruby-core

yep that is correct :slight_smile:

http://github.com/casualjim/ironnails/tree/master/IronNails/vendor/iron_nails/lib/core_ext/kernel.rb

I figure you can wrap that in a begin…rescue block again and first try
the
one with the bool and then the one without it.
Some implementations of Dispose don’t actually implement the method with
a
bool as parameter.

Instead of FileStream you can use the ruby File class or you could write
a
FileStreamAdapter in C# or something so you can safely use it from
IronRuby
without the overloading mayhem.

Cheers
Ivan

When you override a virtual method you’re pushing much more into
CLR-world than when you’re just calling some function on some method.
In the latter case, you shouldn’t have to know that the function you’re
calling is actually defined outside of Ruby, while in the former, this
is a fairly important piece of information.

In any event, I recall that both John and Tomas felt that we shouldn’t
– but no longer remember all the details.

Let’s revisit that later, I’m also not sure what the details were.

Tomas

Well, the interface itself only contains the parameterless method. The
version with the parameter is part of a very common pattern that also
optimizes the finalization experience and plays nicely with derived
classes. If you’re really concerned about cleaning something up, you’ll
probably follow that pattern. But if you’re just interested in the
syntactic sugar of “using” and/or never expect the object’s lifespan to
exceed that of the current method, then there’s no real need to
implement the additional two methods or pay the cost of having a
finalizer. (Even if you suppress it later, creating an object with a
finalizer is more expensive than creating it without one iirc.)

IDisposable is one of my favorite topics. I believe that officially
makes me a masochist.

From: [email protected]
[mailto:[email protected]] On Behalf Of Ivan Porto
Carrero
Sent: Tuesday, September 09, 2008 4:34 AM
To: [email protected]
Subject: Re: [Ironruby-core] Mysteriously broken calls to dispose?

yep that is correct :slight_smile:

http://github.com/casualjim/ironnails/tree/master/IronNails/vendor/iron_nails/lib/core_ext/kernel.rb

I figure you can wrap that in a begin…rescue block again and first try
the one with the bool and then the one without it.
Some implementations of Dispose don’t actually implement the method with
a bool as parameter.

Instead of FileStream you can use the ruby File class or you could write
a FileStreamAdapter in C# or something so you can safely use it from
IronRuby without the overloading mayhem.

Cheers
Ivan

On Tue, Sep 9, 2008 at 1:25 PM, Curt H.
<[email protected]mailto:[email protected]> wrote:

Yes, this has been reported before (in fact, I think it was when someone
was writing “using” ☺) and we haven’t yet worked out a resolution. I’ll
see if there’s something quick that can be fixed here later today.

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Orion E.
Sent: Monday, September 08, 2008 10:12 PM
To: [email protected]mailto:[email protected]
Subject: Re: [Ironruby-core] Mysteriously broken calls to dispose?

Follow-up

If I call $fs.dispose(true), then it works.

It seems there’s a protected dispose(bool) in a derived class.
I can’t actually call Dispose(true) from C# as the compiler tells me
it’s protected.

It strikes me as somewhat broken that the method which ironruby actually
invokes is the one that you shouldn’t invoke…

At any rate, I’d be overjoyed if anyone could point me in the direction
of a fix. I’m trying to write ‘using’ (a la C#) in ruby as part of demo
for my local .NET user group. It should be trivial and showcase how
awesome IronRuby is :frowning:

Orion E. wrote:

I don’t seem to be able to call Dispose on a filestream. Needless to say
this is problematic.

Here’s a paste, straight from the IR console (latest svn version 141)

require ‘mscorlib’

=> true

include System::IO

=> Object

$fs = FileStream.new( ‘file.txt’, FileMode.Open )

=> #System::IO::FileStream:0x000005c

$fs.Dispose

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\matchcaller.generated.cs:30:in
Call2': wrong number or type of arguments for Dispose’ (ArgumentError)

    from 

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\callsite.cs:275:in
`UpdateAndExecute’

    from 

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\updatedelegates.generated.cs:38:in
`Update2’

    from :0

All the other methods on the filestream object work fine (read_all_text,
and so on), but the call to dispose crashes.

Likewise, I get a crash calling methods with overloads, which looks like
it may (??) be related.

require ‘mscorlib’

=> true

include System::IO

=> Object

$bytes = System::IO::File.read_all_bytes( ‘file.txt’ ); nil # nil is to prevent ir from printing the GIANT ARRAY

=> nil

$text = System::Text::Encoding.UTF8.get_string($bytes)

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\matchcaller.generated.cs:35:in
Call3': wrong number or type of arguments for get_string’
(ArgumentError)

    from 

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\callsite.cs:275:in
`UpdateAndExecute’

    from 

c:\development\ironruby\trunk\src\microsoft.scripting.core\actions\updatedelegates.generated.cs:45:in
`Update3’

    from :0

$text = System::Text::Encoding.UTF8.get_string($bytes, 0, $bytes.length)

=> “PROPER TEXT GOES HERE”

It seems like it can’t figure out that there is GetString(bytes) and
GetString(bytes, index, length) and just uses the latter always.
Is there a solution for either of these problems?

Thanks a lot, Orion



Ironruby-core mailing list

[email protected]mailto:[email protected]

http://rubyforge.org/mailman/listinfo/ironruby-core


Ironruby-core mailing list
[email protected]mailto:[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core

Are we going to have “real” properties under the hood, because what we
have
for now is just method with “get_PropertyName”? And this did not play
nicely
with databinding.

I think the same question applies for events as well.

2008/9/9 Curt H. [email protected]

Right now, the only way to get properties is to implement an interface
that defines them. When IronRuby supports this “natively”, it will have
to define a syntax for doing so. That’s because the Ruby language
supports neither properties, attributes nor static types - all of which
will be needed. This will probably involve adding some new methods to
Class that allow you to define typed CLS members. But we don’t have a
specific timeframe for implementing this yet.

From: [email protected]
[mailto:[email protected]] On Behalf Of Stefan D.
Sent: Wednesday, September 10, 2008 2:46 PM
To: [email protected]
Subject: Re: [Ironruby-core] Overriding CLS Virtuals

Are we going to have “real” properties under the hood, because what we
have for now is just method with “get_PropertyName”? And this did not
play nicely with databinding.

I think the same question applies for events as well.

2008/9/9 Curt H.
<[email protected]mailto:[email protected]>

I’ve committed some changes to IronRuby (in SVN revision 141) that let
you implement CLS interfaces and override virtual methods on CLS base
types. Interfaces work like Ruby modules, so to make your class
implement IDisposable you could say

require ‘mscorlib’

class Disposable

include System.IDisposable

def Dispose

# Do something

end

end

You can also override virtual properties. A class or interface that has
the C# declaration “string Value { get; set; }” is overridden from
IronRuby with methods named “Value” for the getter and “Value=” for the
setter.

Note that you need to use the same casing as the CLS definition for both
methods and properties.

We’re just getting started with better .NET interop support and don’t
have very much test coverage yet - but this should let you get going on
some more sophisticated interop scenarios than were previously possible.

Curt H.

[email protected]mailto:[email protected]