Linq etc

Hi

What are the plans regarding Linq support for IronRuby. In the
presentations
I’ve seen you were using vbx to perform linq stuff in Silverlight. Is
that
only applicable to the from … where … select syntax and we can still
use
the extension method syntax collection.where ?

Thanks
Ivan

Ivan Porto C.:

What are the plans regarding Linq support for IronRuby. In the
presentations I’ve seen you were using vbx to perform linq stuff in
Silverlight. Is that only applicable to the from … where … select
syntax and we can still use the extension method syntax
collection.where ?

Yup, you’ll be able to use Linq methods using the normal method call
syntax. There won’t be special syntax.

Translating this example:
Query Syntax and Method Syntax in LINQ (C#) | Microsoft Learn, it will look
something like this:

require ‘System.Core’
numbers = [5, 10, 8, 3, 6, 12]
numbers.where { |num| num % 2 == 0 }.order_by { |n| n }.each { |i|
write("#{i} ") }

  • John

John, my understanding is the Where() and OrderBy() methods are
extension
methods defined in System.Linq.Enumerable and only available in C# if
you
include a reference to the System.Linq namespace in your C# code. Are
you
saying that extension methods are available from IronRuby without having
to
require the namespace? If not, how do we make them available?

Here is an example using an extension method with the signature “public
bool
IsGuid(this String str)” in the class MyString in the namespace
MyAssembly.MyStuff.

C# pseudo code:

using MyAssembly.MyStuff;

public class MyStupidApp() {
public void DoStuff(string val) {
if (val.IsGuid()) Console.WriteLine("Guid!)
}
}

What is the equivalent Ruby code? Do we need to require the assembly?

require ‘MyAssembly.MyStuff’

def do_stuff(val)
puts ‘Guid’ if val.is_guid
end

Or are the Linq extension methods the only ones that will be available?

Thanks!
~Mike

Mike M.:

What is the equivalent Ruby code? Do we need to require the assembly?

require ‘MyAssembly.MyStuff’

def do_stuff(val)
puts ‘Guid’ if val.is_guid
end

Or are the Linq extension methods the only ones that will be available?

Yup, you need to require the assembly. If you were writing Linq in Ruby,
you’d have something like System.Core.rb:

module Enumerable
def order_by

end
def where

end
end

… so requiring System.Core just opens up Enumerable and sticks some
methods on it.
At least, that’s been my thinking on it. Maybe we add an extra step
like:

require ‘System.Core’
include System::Linq

I’m not sure how Ruby-ish that is, though.

  • John

On Jan 21, 2008 4:45 PM, John M. [email protected] wrote:

end
end

… so requiring System.Core just opens up Enumerable and sticks some
methods on it.
At least, that’s been my thinking on it.

I gotcha. So in your example System.Core.rb was monkey-patching
Enumerable. You weren’t actually resolving those method calls to the
extension methods in the System.Linq.Enumerable class.

Maybe we add an extra step like:

require ‘System.Core’
include System::Linq

I’m not sure how Ruby-ish that is, though.

I agree. In C# you add the namespace and those extension methods are
only
available in that source file. So you have to add the namespace to each
file you want to use the extension methods. But in Ruby once they are
added
to the object they are available everywhere. So I wonder what a
Ruby-ish
solution would be. Does anyone on the list have any suggestions how
enabling extension methods could/should look?

Rather than monkey patching Enumerable–thereby affecting (and possibly
tromping over) every object of every class that includes it–how about
extending objects on a case-by-case basis?

I’ve made good use of patterns like the following:

foobar = foo.map { |f| bar(f) }.extend(Statistics)
avg = foobar.avg(:bam)

(where Statistics is a mixin module that implements sum, avg, etc, which
make use of the enumerable methods)

This way any function–including 3rd-party code–that returns an array
or
other enumerable type can be extended on-the-fly and new functions can
return “pre-enriched” collections when appropriate.

numbers = [5, 10, 8, 3, 6, 12].extend(System::Linq)
numbers.where { |num| num % 2 == 0 }.order_by { |n| n }.each { |i|
write("#{i} ") }

Brent

sweet that was what I was thinking.
Thanks for that.

Brent R.:

Rather than monkey patching Enumerable–thereby affecting (and
possibly tromping over) every object of every class that includes
it–how about extending objects on a case-by-case basis?

Hey, this is Ruby, we like to tromp over everything :slight_smile:
Keep in mind Enumerable would resolve its method after the class it’s
included in, so it typically wouldn’t hide existing methods.

can return “pre-enriched” collections when appropriate.

numbers = [5, 10, 8, 3, 6, 12].extend(System::Linq) numbers.where {
|num| num % 2 == 0 }.order_by { |n| n }.each { |i| write("#{i} ") }

Would you really want to do it on a per-object basis though? That’s even
more finer grained than the C# model. Certainly gives you more control,
but I imagine having to do “extend” everywhere could get tedious.

(what we really need here is the Ruby feature “selector namespaces” …
:slight_smile: )

Anyway, we could certainly show the names on a per file basis, e.g.
“using System::Linq”. That might be best.

Of course, there’s also the option to ignore this problem entirely, and
just support the static call syntax:

X = System::Linq::Enumerable.where(numbers) { |num| num % 2 == 0 }
System::Linq::Enumerable.order_by(x) { |n| n }.each { |i| write("#{i} ")
}

That seems pretty bad, however. But maybe it could be hidden behind some
SQL-like DSL magic.

  • John