Replacement idiom for "list_or_nil.to_a"?

R

Rich Morin

Many scripting languages, including Ruby, will "do nothing
gracefully" when asked to iterate through an empty list.
That is, they iterate NO times.

However, many Ruby methods do not return empty lists when
nothing is found. Instead, they return nil. This means
that idioms such as:

list_or_nil.each do |value|
...
end

will fail. As a workaround, I've been using this idiom:

list_or_nil.to_a.each do |value|
...
end


However, I gather that this will soon be deprecated:

http://www.megasolutions.net/ruby/to_a-68350.aspx

This page suggests putting the list in brackets:

[list_or_nil]

but this doesn't solve MY problem:
list_or_nil=nil => nil
[list_or_nil]
=> [nil]

because the loop will now run once with the value nil.
I really dislike having to wrap the iteration block in
an "if" block:

if list_or_nil
list_or_nil.each do |value|
...
end
end

and this is only marginally better:

list_or_nil.each do |value|
...
end if list_or_nil


I suppose I could define my own to_a method for nil,
but that seems a bit questionable, as well. So, is
there a Better Way To Do It?

-r
--
http://www.cfcl.com/rdm Rich Morin
http://www.cfcl.com/rdm/resume (e-mail address removed)
http://www.cfcl.com/rdm/weblog +1 650-873-7841

Technical editing and writing, programming, and web development
 
M

micathom

list_or_nil.each do |value|

If you really want the extra loop in each just to find out that
nothing has to be done, you could also do:

(list_or_nil || []).each do |value|
...
end
 
R

Robert Klemme

Many scripting languages, including Ruby, will "do nothing
gracefully" when asked to iterate through an empty list.
That is, they iterate NO times.

However, many Ruby methods do not return empty lists when
nothing is found. Instead, they return nil. This means
that idioms such as:

list_or_nil.each do |value|
...
end

will fail. As a workaround, I've been using this idiom:

list_or_nil.to_a.each do |value|
...
end


However, I gather that this will soon be deprecated:

http://www.megasolutions.net/ruby/to_a-68350.aspx

This page suggests putting the list in brackets:

[list_or_nil]

but this doesn't solve MY problem:
list_or_nil=nil => nil
[list_or_nil]
=> [nil]

because the loop will now run once with the value nil.
I really dislike having to wrap the iteration block in
an "if" block:

if list_or_nil
list_or_nil.each do |value|
...
end
end

and this is only marginally better:

list_or_nil.each do |value|
...
end if list_or_nil


I suppose I could define my own to_a method for nil,
but that seems a bit questionable, as well. So, is
there a Better Way To Do It?

Probably. How do you like

list_or_nil and list_or_nil.each do |x|
...
end

Or

irb(main):001:0> class NilClass
irb(main):002:1> def each; self; end
irb(main):003:1> include Enumerable
irb(main):004:1> end
=> NilClass
irb(main):005:0> nil.each {|x| puts x}
=> nil
irb(main):006:0>

?

Kind regards

robert
 
D

Daniel DeLorme

Rich said:
will fail. As a workaround, I've been using this idiom:

list_or_nil.to_a.each do |value|
...
end

However, I gather that this will soon be deprecated:

Object#to_a will be deprecated but not nil.to_a, so the
idiom you have above works just fine. It will break if
list_or_nil is a non-array non-nil value but I think
that's as it should be.

Daniel
 
C

Chris Carter

irb(main):001:0> class NilClass
irb(main):002:1> def each; self; end
irb(main):003:1> include Enumerable
irb(main):004:1> end
=> NilClass
irb(main):005:0> nil.each {|x| puts x}
=> nil
irb(main):006:0>

That hack will also make nil.to_a => [].
 
T

Trans

irb(main):001:0> class NilClass
irb(main):002:1> def each; self; end
irb(main):003:1> include Enumerable
irb(main):004:1> end
=> NilClass
irb(main):005:0> nil.each {|x| puts x}
=> nil
irb(main):006:0>

That hack will also make nil.to_a => [].

If the code will be reusable, that's a little too risky.

It would be interesting however for an object to exist, say Void.
Something like:

class Void
def method_missing(*args)
void
end
end

def void
$void ||= Void.new
end

(list_or_nil || void).each { |x| p x }

Though, a core implementation of Void would be much more efficient b/c
it would not need to even bother with method_missing, and just know to
return void and move on.

Hmmm... actually this has been discussed in another context before
(Hash lookup) as Null. Looks like another good reason for it.

T.
 
R

Rich Morin

Thanks for the suggestions! Here's a summary, with comments:
foo.to_a.each {|value| ... }

This is what I was using. It's nice to know that it's not
going away, after all.

foo.to_a.each {|value| ... } if foo

This moves the "if" clause away from the iteration, which
might make it harder to see. Also, it evaluates foo twice
(could duplicate side-effects if foo is a method or be a
performance issue id evaluating foo is expensive).

foo and foo.each {|value| ... }

A bit wordy and obscure. Also, it evaluates foo twice.

class NilClass
def each; self; end
include Enumerable
end

foo.each {|value| ... }

This shortens the usage code, but I don't like playing with
the definition of NilClass. Specifically, this might confuse
a human reader or get in the way of code that already expects
the current behavior.

(foo || []).each {|value| ... }

This smells like line-noise, but is otherwise quite adequate.

(foo || VOID).each {|value| ... }
(foo || void).each {|value| ... }

Aside from the line-noise issue, these seem similar to me.
Both require the use of a supplementary definition, however,
which the reader might have to loop up.

Array(foo).each {|value| ... }

This seems like an improvement, from a clarity standpoint.


My preference, at this point, is for either:
foo.to_a.each {|value| ... }
Array(foo).each {|value| ... }

I think I prefer the latter, from a clarity standpoint. Also,
the fact that to_a is being deprecated in other contexts might
confuse some readers.

If foo is a BIG array, there might be performance differences
between these two, but I'm loathe to second-guess interpreter
implementation issues of this sort...

-r
--
http://www.cfcl.com/rdm Rich Morin
http://www.cfcl.com/rdm/resume (e-mail address removed)
http://www.cfcl.com/rdm/weblog +1 650-873-7841

Technical editing and writing, programming, and web development
 
R

Robert Klemme

Thanks for the suggestions! Here's a summary, with comments:


This is what I was using. It's nice to know that it's not
going away, after all.



This moves the "if" clause away from the iteration, which
might make it harder to see. Also, it evaluates foo twice
(could duplicate side-effects if foo is a method or be a
performance issue id evaluating foo is expensive).



A bit wordy and obscure. Also, it evaluates foo twice.

This is an issue only if foo is a method that does a complex calculation.
class NilClass
def each; self; end
include Enumerable
end

foo.each {|value| ... }

This shortens the usage code, but I don't like playing with
the definition of NilClass. Specifically, this might confuse
a human reader or get in the way of code that already expects
the current behavior.

(foo || []).each {|value| ... }

This smells like line-noise, but is otherwise quite adequate.

(foo || VOID).each {|value| ... }
(foo || void).each {|value| ... }

Aside from the line-noise issue, these seem similar to me.
Both require the use of a supplementary definition, however,
which the reader might have to loop up.

Array(foo).each {|value| ... }

This seems like an improvement, from a clarity standpoint.


My preference, at this point, is for either:
foo.to_a.each {|value| ... }

This might create another object which might impose a performance hit.
I think I prefer the latter, from a clarity standpoint. Also,
the fact that to_a is being deprecated in other contexts might
confuse some readers.

If foo is a BIG array, there might be performance differences
between these two, but I'm loathe to second-guess interpreter
implementation issues of this sort...

There will likely be a performance hit if foo is something different
than an array because then it will have to be converted to an array.

Kind regards

robert
 
T

Trans

Thanks for the suggestions! Here's a summary, with comments:
foo.to_a.each {|value| ... }

This is what I was using. It's nice to know that it's not
going away, after all.
foo.to_a.each {|value| ... } if foo

This moves the "if" clause away from the iteration, which
might make it harder to see. Also, it evaluates foo twice
(could duplicate side-effects if foo is a method or be a
performance issue id evaluating foo is expensive).
foo and foo.each {|value| ... }

A bit wordy and obscure. Also, it evaluates foo twice.
class NilClass
def each; self; end
include Enumerable
end
foo.each {|value| ... }

This shortens the usage code, but I don't like playing with
the definition of NilClass. Specifically, this might confuse
a human reader or get in the way of code that already expects
the current behavior.
(foo || []).each {|value| ... }

A very common idiom in Ruby however.
This smells like line-noise, but is otherwise quite adequate.


Aside from the line-noise issue, these seem similar to me.
Both require the use of a supplementary definition, however,
which the reader might have to loop up.

This is a hypothetical. The significant advantage of "void" would come
from a core implementation which would be much more efficient than [].
(A "void" object would also have some other good uses however. hint
hint matz ;)

T.
 
A

Aníbal

list_or_nil.each do |value| unless list_or_nil.nil?

--
Aníbal Rojas
http://www.rubycorner.com
http://www.hasmanydvelopers.com

Many scripting languages, including Ruby, will "do nothing
gracefully" when asked to iterate through an empty list.
That is, they iterate NO times.

However, many Ruby methods do not return empty lists when
nothing is found. Instead, they return nil. This means
that idioms such as:

list_or_nil.each do |value|
...
end

will fail. As a workaround, I've been using this idiom:

list_or_nil.to_a.each do |value|
...
end

However, I gather that this will soon be deprecated:

http://www.megasolutions.net/ruby/to_a-68350.aspx

This page suggests putting the list in brackets:

[list_or_nil]

but this doesn't solve MY problem:
list_or_nil=nil => nil
[list_or_nil]
=> [nil]

because the loop will now run once with the value nil.
I really dislike having to wrap the iteration block in
an "if" block:

if list_or_nil
list_or_nil.each do |value|
...
end
end

and this is only marginally better:

list_or_nil.each do |value|
...
end if list_or_nil

I suppose I could define my own to_a method for nil,
but that seems a bit questionable, as well. So, is
there a Better Way To Do It?

-r
--http://www.cfcl.com/rdm Rich Morinhttp://www.cfcl.com/rdm/resume (e-mail address removed)://www.cfcl.com/rdm/weblog +1 650-873-7841

Technical editing and writing, programming, and web development
 

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

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top