Addition of 'or' method to String and NilClass in core_ext

5 views
Skip to first unread message

Ryan Angilly

unread,
Jan 28, 2009, 12:45:10 AM1/28/09
to rubyonra...@googlegroups.com
Hey guys,

I find myself doing stuff like this a lot:

   self.email.blank? ? self.name : self.email


Anyone feel like adding an 'or' method to nil and String (a la blank?) so that this will work:


   self.email.or(self.name)


It would be as simple as adding this file to ActiveSupport


activesupport/lib/core_ext/or.rb

class String
  def or(val)
    self == "" ? val : self
  end
end

class NilClass
  def or(val)
    val
  end
end


I'll submit a patch of this + tests to LH if people are interested.

Pascal Ehlert

unread,
Jan 28, 2009, 1:01:08 AM1/28/09
to Ruby on Rails Core
Hi,

How about adding some method #foo instead that returns nil if the string is blank and self otherwise, so that you can do:

self.email.foo || self.name

This looks slightly better and more intuitive to me, if we can figure out a descriptive name for the #foo method (I can’t think of any atm, admittedly).


Cheers

Pascal



On 1/28/09 6:45 AM, "Ryan Angilly" <ang...@gmail.com> wrote:

Hey guys,

I find myself doing stuff like this a lot:

   self.email.blank? ? self.name <http://self.name>  : self.email



Anyone feel like adding an 'or' method to nil and String (a la blank?) so that this will work:


   self.email.or(self.name <http://self.name> )

Mike Gaffney

unread,
Jan 28, 2009, 1:04:02 AM1/28/09
to rubyonra...@googlegroups.com
ifempty?

Chris Eppstein

unread,
Jan 28, 2009, 1:18:18 AM1/28/09
to Ruby on Rails: Core
I do it like this:

http://gist.github.com/53846

Long story short:

>> class Foo
>> attr_accessor :bar
>> nillify_blank :bar
>> end
>> f = Foo.new
=> #<Foo:0x4fe8a68>
>> f.bar = ""
=> ""
>> f.bar
=> nil

Then you can use the || operator naturally.

Chris

On Jan 27, 10:04 pm, Mike Gaffney <mr.ga...@gmail.com> wrote:
> ifempty?
>
> Pascal Ehlert wrote:
> > Hi,
>
> > How about adding some method #foo instead that returns nil if the
> > string is blank and self otherwise, so that you can do:
>
> > self.email.foo || self.name
>
> > This looks slightly better and more intuitive to me, if we can figure
> > out a descriptive name for the #foo method (I can’t think of any atm,
> > admittedly).
>
> > Cheers
>
> > Pascal
>

Rob Biedenharn

unread,
Jan 28, 2009, 1:20:58 AM1/28/09
to rubyonra...@googlegroups.com
Since ActiveSupport already has #blank?, you can easily give yourself
a #nonblank? The symmetry with the Numeric#nonzero? is nice.

-Rob

class String
# Allowing a chain like: string_value.nonblank? || 'default value'
def nonblank?
self unless blank?
end
end

class NilClass
# Allowing a chain like: value.nonblank? || 'default value'
def nonblank?
self
end
# so it plays nicely with Numeric#nonzero?
def nonzero?
self
end
end

Ryan Angilly

unread,
Jan 28, 2009, 1:25:41 AM1/28/09
to rubyonra...@googlegroups.com
I just found out google groups was bouncing my emails because they were coming from a different address, so to sum them all up in one:

I also realized that I do crap like this a lot too:

self.owner_object_association ? self.owner_object_association : default_thing

Where this would give me:

self.owner_object_association.or_if_blank? default_thing


Maybe just add it to Object?

class Object
  def or_if_blank?(val)
    if respond_to? :blank?
      return self.blank? ? val : self
    else
      self
    end
  end
end

class NilClass
  def or_if_blank?(val)
    val
  end
end

That way you get it everywhere blank? is defined (Hash, Array, String, Nil, Numeric)



And the problem with http://gist.github.com/53846 is that I don't think you can do stuff on regular strings like this:

user_msg = params[:stuff].or_if_blank? 'didnt type anything'


-Ryan



On Wed, Jan 28, 2009 at 1:21 AM, Ryan Angilly <ry...@angilly.com> wrote:
But then it wouldn't work on regular strings right?

So you couldn't do things like:

user_msg = params[:stuff].or_if_blank? 'didnt type anything'

tim

unread,
Jan 28, 2009, 11:40:12 AM1/28/09
to Ruby on Rails: Core
+1 for or_if_blank?. Some minor suggestions:

1. I think there does not need to be a special implementation for
NilClass, since nil.blank? => true.

2. I would consider leaving out the "?" from the method name. ?-
methods tend to evaluate to a boolean. This one doesn't.

3. The return can be omitted.

Tim
> And the problem withhttp://gist.github.com/53846is that I don't think you
> can do stuff on regular strings like this:
>
> user_msg = params[:stuff].or_if_blank? 'didnt type anything'
>
> -Ryan
>
> On Wed, Jan 28, 2009 at 1:21 AM, Ryan Angilly <r...@angilly.com> wrote:
> > But then it wouldn't work on regular strings right?
>
> > So you couldn't do things like:
>
> > user_msg = params[:stuff].or_if_blank? 'didnt type anything'
>

Ryan Angilly

unread,
Jan 28, 2009, 12:01:11 PM1/28/09
to rubyonra...@googlegroups.com
+1 for the suggestions.  I'll submit a patch to LH later today.

Ryan Angilly

unread,
Jan 29, 2009, 12:31:12 AM1/29/09
to rubyonra...@googlegroups.com

matthewr...@gmail.com

unread,
Jan 29, 2009, 5:59:21 AM1/29/09
to Ruby on Rails: Core

On Jan 28, 6:25 am, Ryan Angilly <angi...@gmail.com> wrote:
>
> I also realized that I do crap like this a lot too:
>
> self.owner_object_association ? self.owner_object_association :
> default_thing
>
> Where this would give me:
>
> self.owner_object_association.or_if_blank? default_thing

I really don't like "or_if_blank?"
It feels like it should live in a gem,

partly because it doesn't seem necessary,
and partly because there are too many variants I could see people
needing.

or_if_nil
or_if_blank
or_if_present
or_if_a_plate_of_chips

But saying that,

A clear distinctinction needs to be made between;

>> a.blank? ? b : a

and

>> a.or_if_blank?(b)

namely, in the first "b" only gets evaluated ONLY IF "a" is blank
in the second, "b" ALWAYS get evaluated.

It's not necessarily a problem.
But I worry that we'll see code like;

>> a.or_if_blank?
(call_a_function_that_does_something_bad_but_also_returns_something)

Perhaps a different approach would be something like this

>> user.bumblebee
(:full_name, :email, :something_else, :another_fallback)

which is equivalent to;

>> if user.full_name.present?
>> return user.full_name
>> elsif user.email.present?
>> return user.email
>> elsif user.something_else.present?
>> return user.something_else
>> elsif user.another_fallback.present?
>> return user.another_fallback
>> end

The bumblebee hovers around the user,
looking for a flower with some pollen.

It goes from flower to flower,
trying each method in order,
and when it finds one that isn't empty,
it returns it to the hive.

matthewr...@gmail.com

unread,
Jan 29, 2009, 6:47:09 AM1/29/09
to Ruby on Rails: Core

On Jan 29, 10:59 am, "matthewrudyjac...@gmail.com"
<matthewrudyjac...@gmail.com> wrote:
>   >> user.bumblebee
> (:full_name, :email, :something_else, :another_fallback)

I cemented the BumbleBee in a gist.

http://gist.github.com/54501

stephen paul suarez

unread,
Jan 29, 2009, 6:56:45 AM1/29/09
to rubyonra...@googlegroups.com
how do you suggest to make it cater for fallbacks that doesn't necessarily belong to a method
in the object?
e.g.:

user.name.blank? ? user.name : "An arbitrary value"
 
--stephen

matthewr...@gmail.com

unread,
Jan 29, 2009, 7:03:03 AM1/29/09
to Ruby on Rails: Core

On Jan 29, 11:56 am, stephen paul suarez <devpo...@gmail.com> wrote:
> how do you suggest to make it cater for fallbacks that doesn't necessarily
> belong to a method
> in the object?
> e.g.:
>
> user.name.blank? ? user.name : "An arbitrary value"
>
> --stephen

BumbleBees are very versatile creatures.
And they return a nil if they can't find any flowers.

>> user.bumblebee(:name) || "An arbitrary value"

tim

unread,
Jan 29, 2009, 7:07:31 AM1/29/09
to Ruby on Rails: Core
See the discussion on the ticket for a nice lazy evaluation feature
using blocks.

-Tim

On 29 Jan., 13:03, "matthewrudyjac...@gmail.com"
Reply all
Reply to author
Forward
0 new messages