Syntactic sugar buzz

I'm a relative newbie. I'm finally getting the hang of some of the
syntactic sugar provided, such as the whole thing about using the "or"
operator to provide a default value if something is nil:

foo = bar || "emptiness"

One thing I keep running into over and over and over and over that I
wish there was some syntactic sugar for is the whole business of calling
a method on an object, and doing something intelligent if the object is
nil.

If I have a string of stuff like:
blah = foo.bar.split

what if bar is nil? There are obvious long hand ways to deal with this,
but then you loose the smoothness of lining up things like this in Ruby.

I guess what I want is some syntactic sugar that means "this object, or
an empty one of these if this is nil", so that I would get an empty
result instead of a nil object missing method error.

I would like to be able to write:
blah = foo.bar||empty(bar).split

This could be written:
blah = foo.bar||"".split

But that requires a well known object type for bar. What if it is:
blah = foo.bar.whatchamacallit()

where bar is some oddball object of your own imagining.

Have you veteran Rubyists come up with a nice way to write stuff like
this that keeps the nice clean flow of Ruby's chaining in place, but
solves the problems with potentially nil intermediate results?

thanks,
jp

···

--
Posted via http://www.ruby-forum.com/.

blah = (foo.bar || "").split

Works just fine. Not sure what you mean by "well known object type".

T.

···

On Jul 17, 6:52 pm, Jeff Pritchard <j...@jeffpritchard.com> wrote:

I'm a relative newbie. I'm finally getting the hang of some of the
syntactic sugar provided, such as the whole thing about using the "or"
operator to provide a default value if something is nil:

foo = bar || "emptiness"

One thing I keep running into over and over and over and over that I
wish there was some syntactic sugar for is the whole business of calling
a method on an object, and doing something intelligent if the object is
nil.

If I have a string of stuff like:
blah = foo.bar.split

what if bar is nil? There are obvious long hand ways to deal with this,
but then you loose the smoothness of lining up things like this in Ruby.

I guess what I want is some syntactic sugar that means "this object, or
an empty one of these if this is nil", so that I would get an empty
result instead of a nil object missing method error.

I would like to be able to write:
blah = foo.bar||empty(bar).split

This could be written:
blah = foo.bar||"".split

Jeff Pritchard wrote:

I'm a relative newbie. I'm finally getting the hang of some of the
syntactic sugar provided, such as the whole thing about using the "or"
operator to provide a default value if something is nil:

foo = bar || "emptiness"

Please reserve the term "syntactic sugar" for cutesy systems that don't
provide for lean and incredibly expressive statements that scale very well!

If I have a string of stuff like:
blah = foo.bar.split

what if bar is nil?

Large scale, look up something called the "Null Object Refactor". (And note
it's a refactor, not a pattern!)

Then implement it, small scale, like this:

  blah = (foo.bar || '').split

I would like to be able to write:
blah = foo.bar||empty(bar).split

Oooh, at a guess, we could go long-winded again:

  blah = (foo.bar || OpenStruct.new(:split => '')).split

But that requires a well known object type for bar.

Are you coming from Java? Look up "Duck Typing". The /de-facto/ type in our
statement flows right-to-left, not left-to-right like in Java. We need a
thing that can be split, so we get it from a mock object or from .bar. Right
to left.

There might be some way to reduce my OpenStruct experiment. I use that
trick, not small-scale, but large scale, for example with a website that can
entertain both logged-in users and un-logged-in guests. The former don't
deserve a real User model record, so they get an OpenStruct object that
provides the minimum User behavior.

Then I hide this OpenStruct. So you should next think about putting your ||
nil detector _inside_ that bar.

You can generally always get inside a method!

···

--
  Phlip
  Test Driven Ajax (on Rails) [Book]
  "Test Driven Ajax (on Rails)"
  assert_xpath, assert_javascript, & assert_ajax

Jeff Pritchard wrote:

One thing I keep running into over and over and over and over that I
wish there was some syntactic sugar for is the whole business of calling
a method on an object, and doing something intelligent if the object is
nil.

If I have a string of stuff like:
blah = foo.bar.split

what if bar is nil?

Well, yes. What if bar is nil? Do you want blah to be nil? An empty
array?

I personally go with:
  blah = foo.bar.split unless foo.bar.nil?

But really, I think the answer to your question (how do I do what I
want) is the answer to your question (what do I want to do under this
case). It seems that there is no good general answer for "perform the
rough equivalent of method XYZ on nil and give me a reasonable result".

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

Have you veteran Rubyists come up with a nice way to write stuff like
this that keeps the nice clean flow of Ruby's chaining in place, but
solves the problems with potentially nil intermediate results?

I would tend not to view it as a candidate for chaining if I couldn't
be sure that the result of one operation would respond to the next
operation. That's more like a case for conditional flow, so I'd do
something like:

   x = a.b
   y = x.c if x

David

···

On Wed, 18 Jul 2007, Jeff Pritchard wrote:

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

Jeff Pritchard wrote:

One thing I keep running into over and over and over and over that I
wish there was some syntactic sugar for is the whole business of calling
a method on an object, and doing something intelligent if the object is
nil.

This question sure comes back often.

c.f. http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/256556

Daniel

I happen to program in both Groovy and Ruby, and while I prefer Ruby's
paradigms to Groovy's (they're actually geared to make quite different
things convenient), I noticed Groovy's ?. operator and asked myself "Why
doesn't Ruby have this?" The ?. operator in Groovy calls the method if
the expression on the left side is non-null, and returns its value. It
returns null of the object on the left side is null, and never calls the
method. It might be a nice feature to adopt.

Probably the best way to do this in Ruby is
"blah = foo.bar rescue nil", although this has the potential to soak up a
lot of other kinds of errors that you may actually want to propagate.

--Ken

···

On Wed, 18 Jul 2007 10:52:06 +0900, Jeff Pritchard wrote:

I'm a relative newbie. I'm finally getting the hang of some of the
syntactic sugar provided, such as the whole thing about using the "or"
operator to provide a default value if something is nil:

foo = bar || "emptiness"

One thing I keep running into over and over and over and over that I
wish there was some syntactic sugar for is the whole business of calling
a method on an object, and doing something intelligent if the object is
nil.

If I have a string of stuff like:
blah = foo.bar.split

what if bar is nil? There are obvious long hand ways to deal with this,
but then you loose the smoothness of lining up things like this in Ruby.

I guess what I want is some syntactic sugar that means "this object, or
an empty one of these if this is nil", so that I would get an empty
result instead of a nil object missing method error.

I would like to be able to write:
blah = foo.bar||empty(bar).split

This could be written:
blah = foo.bar||"".split

But that requires a well known object type for bar. What if it is: blah
= foo.bar.whatchamacallit()

where bar is some oddball object of your own imagining.

Have you veteran Rubyists come up with a nice way to write stuff like
this that keeps the nice clean flow of Ruby's chaining in place, but
solves the problems with potentially nil intermediate results?

thanks,
jp

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

It feels like it could be shortened, perhaps the :type is unnecessary,
but I was thinking of something like this for my DataMapper to ease
the pain of using object graphs in simple tabular reporting views...

  class Object
    def default(type)
      self || type.new
    end
  end

  class Person
    attr_accessor :name
    def initialize(name)
      @name = name
    end
  end

  people = [ Person.new('Bob'), nil ]

  for person in people
    puts "Hello " + person.default(Person).name
  end

Which isn't _too_ ugly I think. On the other hand you could end up
with something like this:

  puts @photo.default(Article).article.default(Category).category.name

Instead of:

  puts @photo.article.category.name

But that's obviously more than a bit contrived. Any ideas would be
welcome though...

···

On Jul 17, 8:52 pm, Jeff Pritchard <j...@jeffpritchard.com> wrote:

I'm a relative newbie. I'm finally getting the hang of some of the
syntactic sugar provided, such as the whole thing about using the "or"
operator to provide a default value if something is nil:

foo = bar || "emptiness"

One thing I keep running into over and over and over and over that I
wish there was some syntactic sugar for is the whole business of calling
a method on an object, and doing something intelligent if the object is
nil.

If I have a string of stuff like:
blah = foo.bar.split

what if bar is nil? There are obvious long hand ways to deal with this,
but then you loose the smoothness of lining up things like this in Ruby.

I guess what I want is some syntactic sugar that means "this object, or
an empty one of these if this is nil", so that I would get an empty
result instead of a nil object missing method error.

I would like to be able to write:
blah = foo.bar||empty(bar).split

This could be written:
blah = foo.bar||"".split

But that requires a well known object type for bar. What if it is:
blah = foo.bar.whatchamacallit()

where bar is some oddball object of your own imagining.

Have you veteran Rubyists come up with a nice way to write stuff like
this that keeps the nice clean flow of Ruby's chaining in place, but
solves the problems with potentially nil intermediate results?

thanks,
jp

--
Posted viahttp://www.ruby-forum.com/.

Trans wrote:

Works just fine. Not sure what you mean by "well known object type".

I think he means you cant use this if the object on the right of ||
doesn't have the method defined.

So (foo.bar || "").split works but (foo.bar || "").blah() doesn't.

···

--
Posted via http://www.ruby-forum.com/\.

Trans wrote:

This could be written:
blah = foo.bar||"".split

blah = (foo.bar || "").split

Works just fine. Not sure what you mean by "well known object type".

What if split were another method, something that only real 'bar's can do?

···

--
  Phlip
  Test Driven Ajax (on Rails) [Book]
  "Test Driven Ajax (on Rails)"
  assert_xpath, assert_javascript, & assert_ajax

I tend to use "syntactic sugar" to refer to a way to make something look
more succinct and pretty, but that isn't strictly necessary, e.g.:

  a, b = b, a

. . . is syntactic sugar for:

  c = a; a = b; b = c

Whether it's "cutesy" or "scales well" is kind of immaterial, as far as
I'm concerned.

···

On Wed, Jul 18, 2007 at 12:40:12PM +0900, Phlip wrote:

Jeff Pritchard wrote:

> I'm a relative newbie. I'm finally getting the hang of some of the
> syntactic sugar provided, such as the whole thing about using the "or"
> operator to provide a default value if something is nil:
>
> foo = bar || "emptiness"

Please reserve the term "syntactic sugar" for cutesy systems that don't
provide for lean and incredibly expressive statements that scale very well!

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
Amazon.com interview candidate: "When C++ is your hammer, everything starts
to look like your thumb."

If it were me, I'd simply rescue a method-not-existent error and
return an empty dataset.

What do you guys think? It can even be made a method that accepts a block...

Aur

Sometimes I think the brackets spoil how the expression reads. You could
define a method that looks like this:

blah = foo.bar.or("").split

Trainwreck though...

Dan

···

On Jul 17, 6:52 pm, Jeff Pritchard <j...@jeffpritchard.com> wrote:

This could be written:
blah = (foo.bar||"").split

--
Posted via http://www.ruby-forum.com/\.

First derogatory references to "monkey-patching" and now this -
whatever happened to the spirit of ruby? I thought we *liked*
syntactic sugar (otherwise we'd all just go use lisp).

martin

···

On 7/18/07, Phlip <phlipcpp@yahoo.com> wrote:

Please reserve the term "syntactic sugar" for cutesy systems that don't
provide for lean and incredibly expressive statements that scale very well!

Phlip wrote:

Please reserve the term "syntactic sugar" for cutesy systems that don't provide for lean and incredibly expressive statements that scale very well!
  
I have a nagging suspicion that Matz himself has used this term. It is certainly not a derogatory term when used within the Ruby community and I have a feeling that it is not a derogatory term anywhere else either. It is simply a description of a feature of a language. Many languages have syntactic sugar, heck arrays in C are syntactic sugar. The line "a += 12" is syntactic sugar for "a = a + 12", Ruby has benefited greatly from "syntactic sugar" (as have many other languages), just imaging the outcry that there would be if it was all stripped from the language. Image how much slower the language would have taken up if we had to enter all our code in long form. There is enough kvetching from C/C++ and Java programmer about the lack of pre and post ++/-- operators to show how important syntactic sugar is to people.

Let us not disrespect our heritage even if it is not very "Enterprisey".

Would be interesting discussing this. I shall have a look at some of
my code how that would change, looks ugly at first, but that normally
changes when getting the habit.
Robert

···

On 7/18/07, Ken Bloom <kbloom@gmail.com> wrote:

I happen to program in both Groovy and Ruby, and while I prefer Ruby's
paradigms to Groovy's (they're actually geared to make quite different
things convenient), I noticed Groovy's ?. operator and asked myself "Why
doesn't Ruby have this?" The ?. operator in Groovy calls the method if
the expression on the left side is non-null, and returns its value. It
returns null of the object on the left side is null, and never calls the
method. It might be a nice feature to adopt.

Probably the best way to do this in Ruby is
"blah = foo.bar rescue nil", although this has the potential to soak up a
lot of other kinds of errors that you may actually want to propagate.

--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck

> I'm a relative newbie. I'm finally getting the hang of some of the
> syntactic sugar provided, such as the whole thing about using the "or"
> operator to provide a default value if something is nil:
>
> foo = bar || "emptiness"
>
> One thing I keep running into over and over and over and over that I
> wish there was some syntactic sugar for is the whole business of calling
> a method on an object, and doing something intelligent if the object is
> nil.
>
> If I have a string of stuff like:
> blah = foo.bar.split
>
> what if bar is nil? There are obvious long hand ways to deal with this,
> but then you loose the smoothness of lining up things like this in Ruby.
>
> I guess what I want is some syntactic sugar that means "this object, or
> an empty one of these if this is nil", so that I would get an empty
> result instead of a nil object missing method error.
>
> I would like to be able to write:
> blah = foo.bar||empty(bar).split
>
> This could be written:
> blah = foo.bar||"".split
>
> But that requires a well known object type for bar. What if it is:
> blah = foo.bar.whatchamacallit()
>
> where bar is some oddball object of your own imagining.
>
> Have you veteran Rubyists come up with a nice way to write stuff like
> this that keeps the nice clean flow of Ruby's chaining in place, but
> solves the problems with potentially nil intermediate results?
>
> thanks,
> jp
>
> --
> Posted viahttp://www.ruby-forum.com/.

It feels like it could be shortened, perhaps the :type is unnecessary,
but I was thinking of something like this for my DataMapper to ease
the pain of using object graphs in simple tabular reporting views...

  class Object
    def default(type)
      self || type.new
    end
  end

  class Person
    attr_accessor :name
    def initialize(name)
      @name = name
    end
  end

  people = [ Person.new('Bob'), nil ]

  for person in people
    puts "Hello " + person.default(Person).name
  end

I think you can save more typing if you default the type parameter to
self.class. Then you have

puts "Hello " + person.default.name

Which isn't _too_ ugly I think. On the other hand you could end up
with something like this:

  puts @photo.default(Article).article.default(Category).category.name

Instead of:

  puts @photo.article.category.name

But that's obviously more than a bit contrived. Any ideas would be
welcome though...

Hm... One thing I do not like about this is that there has to be a
new object created for every "missing" instance. I'd do your sample
differently: either remove nils from the array beforehand or add a "
if person" at the end of the "puts" statement.

Kind regards

robert

···

2007/7/19, Sam Smoot <ssmoot@gmail.com>:

On Jul 17, 8:52 pm, Jeff Pritchard <j...@jeffpritchard.com> wrote:

Daniel Lucraft wrote:

This could be written:
blah = (foo.bar||"").split

Sometimes I think the brackets spoil how the expression reads. You could
define a method that looks like this:

blah = foo.bar.or("").split

Trainwreck though...

Dan

Thanks everyone. This has at least convinced me that I wasn't missing
some well known way to do this.

My choice of split confused the issue. I should have used something
unknown like "fred".

I was looking for a solution which, like the || operator, works with all
object types, not just a string object, so that it could be used as a
general rather than a specific solution.

In other words, the (something || "") solution works for split, because
there is a convenient syntax for "empty string".

I was hoping for a more general (something ||
whateverneedstobeheretomakewhatfollowsworkright).fred

As another poster mentioned or hinted at, since "something" may not have
a type yet, there's no way to get the needed object type from that. I
was hoping for something that can't be done without mind reading
interpreters.

Ruby rocks, but it still lacks a generalized "you know what I mean"
operator. :slight_smile:

jp

···

On Jul 17, 6:52 pm, Jeff Pritchard <j...@jeffpritchard.com> wrote:

--
Posted via http://www.ruby-forum.com/\.

Then just use:

blah = foo.bar.to_s.split

It's the same thing in this case.

James Edward Gray II

···

On Jul 18, 2007, at 1:50 AM, Daniel Lucraft wrote:

On Jul 17, 6:52 pm, Jeff Pritchard <j...@jeffpritchard.com> wrote:

This could be written:
blah = (foo.bar||"").split

Sometimes I think the brackets spoil how the expression reads. You could
define a method that looks like this:

blah = foo.bar.or("").split

Trainwreck though...

Daniel Lucraft wrote:
>>> This could be written:
>>> blah = (foo.bar||"").split
>
> Sometimes I think the brackets spoil how the expression reads. You could
> define a method that looks like this:
>
> blah = foo.bar.or("").split
>
> Trainwreck though...
>
> Dan

Thanks everyone. This has at least convinced me that I wasn't missing
some well known way to do this.

I believe another (obvious?) solution has not been mentioned so far:

# note, I used the empty array as replacement
# because split would return an array
blah = foo.bar.split rescue

I find it pretty elegant, too.

I was looking for a solution which, like the || operator, works with all
object types, not just a string object, so that it could be used as a
general rather than a specific solution.

In other words, the (something || "") solution works for split, because
there is a convenient syntax for "empty string".

I was hoping for a more general (something ||
whateverneedstobeheretomakewhatfollowsworkright).fred

As another poster mentioned or hinted at, since "something" may not have
a type yet, there's no way to get the needed object type from that.

Well, you do not need the type. You just need the method signature.
I.e., in your case something like this would be sufficient:

o=Object.new
def o.fred() your_default_value end

I was hoping for something that can't be done without mind reading
interpreters.

"can" or "can't"?

Ruby rocks, but it still lacks a generalized "you know what I mean"
operator. :slight_smile:

Hm...

Kind regards

robert

···

2007/7/18, Jeff Pritchard <jp@jeffpritchard.com>:

>> On Jul 17, 6:52 pm, Jeff Pritchard <j...@jeffpritchard.com> wrote: