From: RichardOnRails Date: 2008-08-30T12:00:05+09:00 Subject: Re: assignment operator that treats empty and nil as the same thing On Aug 29, 10:21 pm, RichardOnRails wrote: > On Aug 29, 6:01 pm, "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 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