[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Emulating a Groovy feature?

John Wells

8/18/2007 12:37:00 PM

Guys,

There's something called Safe Navigation in Groovy (http://groovy.codehaus.org/Statements#Statements-Safe...) that I find very appealing.

So, Groovy will allow you to safely walk an object graph, even if that graph has nulls in it (the walk will short circuit):

def foo = null
def bar = foo?.something?.myMethod()
assert bar == null

Is there an easy way to hack an equivalent out in Ruby?

Thanks,
John

17 Answers

Xavier Noria

8/18/2007 12:50:00 PM

0


On Aug 18, 2007, at 2:36 PM, John Wells wrote:

> Guys,
>
> There's something called Safe Navigation in Groovy (http://
> groovy.codehaus.org/Statements#Statements-Safenavigation) that I
> find very appealing.
>
> So, Groovy will allow you to safely walk an object graph, even if
> that graph has nulls in it (the walk will short circuit):
>
> def foo = null
> def bar = foo?.something?.myMethod()
> assert bar == null
>
> Is there an easy way to hack an equivalent out in Ruby?

Sure, NilClass can be reopened just fine:

class NilClass
def method_missing(name, *args)
nil
end
end

nil.invoices.find(5) # -> nil

Reopening NilClass is something really handy sometimes.

-- fxn


Dave Burt

8/18/2007 12:51:00 PM

0

John Wells wrote:
> Guys,
>
> There's something called Safe Navigation in Groovy (http://groovy.codehaus.org/Statements#Statements-Safe...) that I find very appealing.
>
> So, Groovy will allow you to safely walk an object graph, even if that graph has nulls in it (the walk will short circuit):
>
> def foo = null
> def bar = foo?.something?.myMethod()
> assert bar == null
>
> Is there an easy way to hack an equivalent out in Ruby?

irb(main):001:0> def nil.method_missing(*_) end
=> nil
irb(main):002:0> nil.a.b.c
=> nil

Cheers,
Dave

Arlen Cuss

8/18/2007 12:56:00 PM

0


>
> Sure, NilClass can be reopened just fine:
>
> class NilClass
> def method_missing(name, *args)
> nil
> end
> end
>
> nil.invoices.find(5) # -> nil


The only problem I can see here is that it's not quite optional.

Arlen


Xavier Noria

8/18/2007 1:14:00 PM

0

On Aug 18, 2007, at 2:55 PM, Arlen Christian Mart Cuss wrote:

>> Sure, NilClass can be reopened just fine:
>>
>> class NilClass
>> def method_missing(name, *args)
>> nil
>> end
>> end
>>
>> nil.invoices.find(5) # -> nil
>
>
> The only problem I can see here is that it's not quite optional.

Yeah, that's the basic technique.

You could use some naming convention as in Groovy as well (which you
would check in the body of method_missing), or perhaps wrap the
activation of that catchall in a block like this:

with_safe_navigation do
regular code
end

Once you can reopen NilClass like that I think there are ways to
emulate that feature.

-- fxn


Stefan Rusterholz

8/18/2007 1:33:00 PM

0

John Wells wrote:
> Guys,
>
> There's something called Safe Navigation in Groovy
> (http://groovy.codehaus.org/Statements#Statements-Safe...) that I
> find very appealing.
>
> So, Groovy will allow you to safely walk an object graph, even if that
> graph has nulls in it (the walk will short circuit):
>
> def foo = null
> def bar = foo?.something?.myMethod()
> assert bar == null
>
> Is there an easy way to hack an equivalent out in Ruby?
>
> Thanks,
> John

Good to see that I'm not alone on this :)
I still intend to write an RCR for this. You might want to read through
http://www.ruby-...to...

Regards
Stefan
--
Posted via http://www.ruby-....

Robert Klemme

8/20/2007 9:06:00 AM

0

2007/8/18, John Wells <lists@sourceillustrated.com>:
> Guys,
>
> There's something called Safe Navigation in Groovy (http://groovy.codehaus.org/Statements#Statements-Safe...) that I find very appealing.
>
> So, Groovy will allow you to safely walk an object graph, even if that graph has nulls in it (the walk will short circuit):
>
> def foo = null
> def bar = foo?.something?.myMethod()
> assert bar == null
>
> Is there an easy way to hack an equivalent out in Ruby?

Try this in IRB

class Object
class Holder
def __ref() @ref end

def initialize(ref,&b)
@ref = ref
instance_eval(&b)
end

def method_missing(s,*a,&b)
@ref = @ref.send(s,*a,&b) rescue nil
self
end
end

def safe(&b)
Holder.new(self,&b).__ref
end
end
F = Struct.new :name
f=F.new "foo"
f.safe { name.size > 10 }
f.safe { name.xxx }

Not too nice though...

Kind regards

robert

Robert Klemme

8/20/2007 9:07:00 AM

0

2007/8/20, Robert Klemme <shortcutter@googlemail.com>:
> 2007/8/18, John Wells <lists@sourceillustrated.com>:
> > Guys,
> >
> > There's something called Safe Navigation in Groovy (http://groovy.codehaus.org/Statements#Statements-Safe...) that I find very appealing.
> >
> > So, Groovy will allow you to safely walk an object graph, even if that graph has nulls in it (the walk will short circuit):
> >
> > def foo = null
> > def bar = foo?.something?.myMethod()
> > assert bar == null
> >
> > Is there an easy way to hack an equivalent out in Ruby?
>
> Try this in IRB
>
> class Object
> class Holder
> def __ref() @ref end
>
> def initialize(ref,&b)
> @ref = ref
> instance_eval(&b)
> end
>
> def method_missing(s,*a,&b)
> @ref = @ref.send(s,*a,&b) rescue nil
> self
> end
> end
>
> def safe(&b)
> Holder.new(self,&b).__ref
> end
> end
> F = Struct.new :name
> f=F.new "foo"
> f.safe { name.size > 10 }
> f.safe { name.xxx }
>
> Not too nice though...
>
> Kind regards
>
> robert

PS: Forgot to mention: you can always use the "rescue" modifier:

x = foo.bar.baz rescue nil

Jake Cutter

11/21/2007 5:25:00 PM

0

On Aug 20, 2007 4:07 AM, Robert Klemme <shortcutter@googlemail.com> wrote:
> x = foo.bar.baz rescue nil

Interesting thread....glad someone else has hit this need.

How does the above work, exactly? You're rescuing without a block?
Doesn't it have to be something like:

begin
x = foo.bar.baz
rescue nil
end

? At least the documentation would suggest so...

Thanks,
Jake

Jason Roelofs

11/21/2007 6:11:00 PM

0

Note: parts of this message were removed by the gateway to make it a legal Usenet post.

On Nov 21, 2007 12:24 PM, Jake Cutter <cutter38@gmail.com> wrote:

> On Aug 20, 2007 4:07 AM, Robert Klemme <shortcutter@googlemail.com> wrote:
> > x = foo.bar.baz rescue nil
>
> Interesting thread....glad someone else has hit this need.
>
> How does the above work, exactly? You're rescuing without a block?
> Doesn't it have to be something like:
>
> begin
> x = foo.bar.baz
> rescue nil
> end
>
> ? At least the documentation would suggest so...
>
> Thanks,
> Jake
>
>
You don't need begin unless you want to catch just a section of code. Single
lines works wonders for concise error handling, such as

this_method_can_throw rescue "default value"

Or for a full method (Rails)

def action
does_stuff_that_can_throw
rescue
default_error_handling
end

Ruby's awesome.

Jason

Robert Klemme

11/21/2007 7:38:00 PM

0

On 21.11.2007 18:24, Jake Cutter wrote:
> On Aug 20, 2007 4:07 AM, Robert Klemme <shortcutter@googlemail.com> wrote:
>> x = foo.bar.baz rescue nil
>
> Interesting thread....glad someone else has hit this need.
>
> How does the above work, exactly? You're rescuing without a block?
> Doesn't it have to be something like:
>
> begin
> x = foo.bar.baz
> rescue nil
> end
>
> ? At least the documentation would suggest so...

The value of the expression is replaced by the value of the expression
after the "rescue" in this form. And no, you don't need a block. The
Pickaxe 1st edition does not seem to mention it but it's definitively a
legal Ruby feature.

Kind regards

robert