Assignment operator that treats empty and nil as the same thing

Maybe I can redeem myself: Matt gave you a great solution in reopening
the Hash definition. I recommend a minor improvement as follows:

class Hash
  alias_method "orig_fetch", ""
  def (what)
      result = orig_fetch(what)
      result = nil if result == ''
  end
end

### test1
otest = {}
otest['first_name'] ||= 'homer'
puts otest.inspect #= {"first_name"=>"homer"}

### test2
otest = {'first_name'=>''}
otest['first_name'] ||= 'homer'
puts otest.inspect #= {"first_name"=>"homer"}

HTH,
Richard

···

On Aug 29, 10:21 pm, RichardOnRails <RichardDummyMailbox58...@uscomputergurus.com> wrote:

On Aug 29, 6:01 pm, "scoot...@hotmail.com" <scoot...@hotmail.com> > wrote:

> ### test1
> otest = {};
> otest['first_name'] ||= 'homer';
> puts otest.inspect;

> ### test2
> otest = {'first_name'=>''};
> otest['first_name'] ||= 'homer';
> puts otest.inspect;

> Problem: test1 produces the correct output, but test2 produces
> unwanted output (the value remains as an empty string). I realize that
> ruby treats the empty string as "true" ... nevertheless I want to find
> an assignment operator in ruby that treats nil and empty exactly the
> same way, with the behavior shown in test1.

> Question: Is there a way to do this in ruby *without* resorting to an
> if statement or some other construct such as:

> otest['first_name'] = (otest['first_name'].empty?) 'homer' :
> otest['first_name'];

> I would like to handle this with a *single* assignment operator, just
> like you can do in test1.

The problem is that you think that otest['first_name] is nil in both
tests when you try the conditional assignment. As the following code
shows it's only nil the first time; the second time it's (an empty)
String.

otest = {};
puts otest['first_name'] .class.to_s
otest['first_name'] ||= 'homer';
puts otest.inspect;

### test2
otest = {'first_name'=>''};
puts otest['first_name'] .class.to_s
otest['first_name'] ||= 'homer';
puts otest.inspect;

HTH,
Richard

In my view that's abusing open classes. Ruby has well-defined boolean
semantics, and Hash# is a fundamental method. People have
expectations about those ones.

In this case I think it could be better just to program explicitly
your particular logic, either by hand, or in an clear separate method
set_if_blank(key, value). I believe that one may be added to Hash if
it deserves it in your app.

···

On Sat, Aug 30, 2008 at 5:00 AM, RichardOnRails <RichardDummyMailbox58407@uscomputergurus.com> wrote:

Maybe I can redeem myself: Matt gave you a great solution in reopening
the Hash definition. I recommend a minor improvement as follows:

class Hash
alias_method "orig_fetch", ""
def (what)
     result = orig_fetch(what)
     result = nil if result == ''
end
end

Xavier Noria wrote:

Maybe I can redeem myself: Matt gave you a great solution in reopening
the Hash definition. I recommend a minor improvement as follows:

class Hash
alias_method "orig_fetch", ""
def (what)
     result = orig_fetch(what)
     result = nil if result == ''
end
end

In my view that's abusing open classes. Ruby has well-defined boolean
semantics, and Hash# is a fundamental method. People have
expectations about those ones.

I agree with that. But if it's just one hash object that causes you
problems, you can always change the method in the object's eigenclass:

class << your_hash_object
  alias_method "origfetch", ""
  def (what)
    result = origfetch(what)
    if result == ''
      nil
    else
      result
    end
  end
end

This way you won't break the existing functionality for other hashes.

Or you could simply extend the class, modify the method in the
descendant class, and make all your hashes instances of the descendant
class.

TPR.

···

On Sat, Aug 30, 2008 at 5:00 AM, RichardOnRails > <RichardDummyMailbox58407@uscomputergurus.com> wrote:

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