assignment operator that treats empty and nil as the same thing

S

scooterm

### 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.
 
M

matt neuburg

### 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.

Would it suffice to subvert Hash in such a way that the value of an
element whose value is the empty string is reported as nil?

class Hash
alias_method "origfetch", "[]"
def [](what)
result = origfetch(what)
if result == ''
nil
else
result
end
end
end

h = {"hey"=>"", "ho"=>"ha"}
h["hey"] ||= "homer"
p h

If that's too strong, you can devise your own function:

class Hash
def set_if_empty(k,v)
cur = self[k]
if cur.nil? || cur == ''
self[k] = v
end
end
end

h = {"hey"=>"", "ho"=>"ha"}
h.set_if_empty("hey", "homer")
p h
 
R

RichardOnRails

### 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
 
R

RichardOnRails

### 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

Woops. I only glanced at your post when I responded. I only
belatedly noticed that you understood the nil and and an empty string
were involved. My apologies.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top