Puts *(1..10) what's that star

puts *(1…10)

What is the star operator called and where can I get more information
about it. How does it work? It’s hard to search without knowing what
the operator is called?

On Oct 22, 6:45 am, “Neeraj K.” [email protected] wrote:

puts *(1…10)

What is the star operator called and where can I get more information
about it. How does it work? It’s hard to search without knowing what
the operator is called?

splat

http://redhanded.hobix.com/bits/theSiphoningSplat.html

I’m not sure how this code works.

BOARD_MEMBERS = [‘Jan’, ‘Julie’, ‘Archie’, ‘Stewick’]HISTORIANS =
[‘Braith’, ‘Dewey’, ‘Eduardo’]

case name
when *BOARD_MEMBERS
“You’re on the board! A congratulations is in order.”
when *HISTORIANS
“You are busy chronicling every deft play.”
when *HISTORIANS|BOARD_MEMBERS
“We welcome you all to the First International
Symposium of Board Members and Historians Alike.”
end

Any explanations.

On 10/24/07, Neeraj K. [email protected] wrote:

when *BOARD_MEMBERS
“You’re on the board! A congratulations is in order.”
when *HISTORIANS
“You are busy chronicling every deft play.”

when *HISTORIANS|BOARD_MEMBERS
“We welcome you all to the First International
Symposium of Board Members and Historians Alike.”
end

The splat “unrolls” the BOARD_MEMBERS array into a list of values.
It’s the same as writing

case name
when ‘Jan’, ‘Julie’, ‘Archie’, ‘Stewick’
…blah

quite clever, actually. If you didn’t have splat, you’d have to do
something like:

case
when BOARD_MEMBERS.include?(name)
…blah

Thanks guys.
I guess this is what Ruby idiom is all about. To newbies it looks strage
but
rubyists are comfortable using such operators.

  • Neeraj

Hi –

On Mon, 22 Oct 2007, gene tani wrote:

On Oct 22, 6:45 am, “Neeraj K.” [email protected] wrote:

puts *(1…10)

What is the star operator called and where can I get more information
about it. How does it work? It’s hard to search without knowing what
the operator is called?

splat

AKA (by me, anyway) the unary unarray operator.

David


Upcoming training by David A. Black/Ruby Power and Light, LLC:

  • Advancing With Rails, Edison, NJ, November 6-9
  • Advancing With Rails, Berlin, Germany, November 19-22
  • Intro to Rails, London, UK, December 3-6 (by Skills Matter)
    See http://www.rubypal.com for details!

On Oct 24, 2007, at 10:28 AM, Bob S. wrote:

case
when BOARD_MEMBERS.include?(name)
…blah

How costly is doing it the “splat” way? It’s amazing (to me) that it
can be written that way. Does it actually have to create the unrolled
list? And should I not fret over such things and just write it the
clean way?

On 10/24/07, David A. Black [email protected] wrote:

On Mon, 22 Oct 2007, gene tani wrote:

On Oct 22, 6:45 am, “Neeraj K.” [email protected] wrote:

What is the star operator called and where can I get more information
about it. How does it work? It’s hard to search without knowing what
the operator is called?

splat

AKA (by me, anyway) the unary unarray operator.

Which, I for one, greatly prefer to splat.

Although when used on the other side of assignments as in

*a = 1, 2,3

def foo(*parms)
end

{:a => 1, :b => 2}.each {|*assoc_array| …}

neither name seems to fit.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Oct 24, 2007, at 12:42 PM, George B. wrote:

case
when BOARD_MEMBERS.include?(name)
…blah

How costly is doing it the “splat” way? It’s amazing (to me) that
it can be written that way. Does it actually have to create the
unrolled list? And should I not fret over such things and just
write it the clean way?

Seems like Array#=== ought to override Object#=== to behave more like
Range#=== and test for inclusion (i.e., like an alias of
Array#include?). If it did, then you could avoid the splat overhead
(whatever it might be) and the “.include?(name)” duplication on each
‘when’ clause.

Is there really any good reason for Array#=== to do anything else, in
other words, does anyone rely on the current behavior that mimics
Array#== anyway?

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

On 10/24/07, Rob B. [email protected] wrote:

Seems like Array#=== ought to override Object#=== to behave more like
Range#=== and test for inclusion (i.e., like an alias of Array#include?).
If it did, then you could avoid the splat overhead (whatever it might be)
and the “.include?(name)” duplication on each ‘when’ clause.

Is there really any good reason for Array#=== to do anything else, in other
words, does anyone rely on the current behavior that mimics Array#== anyway?

Because then

[1, 2, 3] === [1, 2, 3]
would become false, and that would probably do more harm than good.

Rather than assuming there’s a huge overhead to *, or any overhead at
all, why not do some benchmarks and get back to us.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Oct 24, 2007, at 3:03 PM, Rick DeNatale wrote:

list? And
in other


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

OK, include? does win over * and === comes in between (with my simple
implementation).

As for ===, my curiosity is who actually relies on Array#=== since it
is just Object#=== and equivalent to ==.

No one seems to confuse Ranges this way:

(1…10) == (1…10) #=> false
(1…10) == 5 #=> false
(1…10) === 5 #=> true

Anyway, here’s the “proof”:

require ‘benchmark’
include Benchmark

MONTH_WORDS = %w[ january february march april may june july august
september october november december ]
DAY_WORDS = %w[ sunday monday tuesday wednesday thursday friday
saturday ]
NUMBERS = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41 ]
test_words = %w[ january july december sunday wednesday saturday ruby
foo ]
test_numbers = [ 2, 4, 7, 17, 21, 29, 41, 42 ]

bm(18) do |x|
x.report(“unary unarray”) { 100_000.times {
test_words.each { |word|
case word
when *MONTH_WORDS : ‘month’
when *DAY_WORDS : ‘day’
else ‘neither’
end
}
test_numbers.each { |number|
case number
when *NUMBERS : ‘match’
else ‘nope’
end
}
} }

x.report(“.include?”) { 100_000.times {
test_words.each { |word|
case
when MONTH_WORDS.include?(word) : ‘month’
when DAY_WORDS.include?(word) : ‘day’
else ‘neither’
end
}
test_numbers.each { |number|
case
when NUMBERS.include?(number) : ‘match’
else ‘nope’
end
}
} }

class Array
def === obj
include?(obj)
end
end
x.report(“override Array#===”) { 100_000.times {
test_words.each { |word|
case word
when MONTH_WORDS : ‘month’
when DAY_WORDS : ‘day’
else ‘neither’
end
}
test_numbers.each { |number|
case number
when NUMBERS : ‘match’
else ‘nope’
end
}
} }

end
END
-- mode: compilation; default-directory: “~/code/ruby/” --
Compilation started at Wed Oct 24 17:44:51

ruby unarray_or_include_benchmark.rb
user system total real
unary unarray 5.050000 0.020000 5.070000 ( 5.182787)
.include? 3.560000 0.010000 3.570000 ( 3.629457)
override Array#=== 4.110000 0.010000 4.120000 ( 4.218315)

Compilation finished at Wed Oct 24 17:45:04

Rob B. http://agileconsultingllc.com
[email protected]

Hi –

On Wed, 24 Oct 2007, Rick DeNatale wrote:

splat

AKA (by me, anyway) the unary unarray operator.

Which, I for one, greatly prefer to splat.

Although when used on the other side of assignments as in

*a = 1, 2,3

The way I see it this:

*a = 1,2,3 means: assign to a that which, when unarrayed, is the
list 1,2,3 – namely, the array [1,2,3]. A stretch, perhaps, but it
sort of makes sense :slight_smile:

Of course:

a = 1,2,3

does the same thing. But that’s just the rule about one argument on
the lhs sponging up all the things on the lhs in array form.

def foo(*parms)
end

Let’s say you call: foo(1,2,3). That means that the bare list 1,2,3 is
equivalent to an unarrayed parms (i.e., *parms) – so parms must be
the array [1,2,3].

{:a => 1, :b => 2}.each {|*assoc_array| …}

Ditto-ish, I think.

neither name seems to fit.

Probably not perfectly, but I think that overall it does behave in an
‘unarray’ way – that is, *a always means an array a that corresponds
to a bare list of items. In any event, ‘splat’ does nothing for me.

David


Upcoming training by David A. Black/Ruby Power and Light, LLC:

  • Advancing With Rails, Edison, NJ, November 6-9
  • Advancing With Rails, Berlin, Germany, November 19-22
  • Intro to Rails, London, UK, December 3-6 (by Skills Matter)
    See http://www.rubypal.com for details!

On 10/24/07, Rob B. [email protected] wrote:

OK, include? does win over * and === comes in between (with my simple
implementation).

As for ===, my curiosity is who actually relies on Array#=== since it
is just Object#=== and equivalent to ==.

Any code which uses arrays as case discriminators would break on the
change.

case x
when [:fred, :ethel]

when [:ricky, :lucy]

No one seems to confuse Ranges this way:

(1…10) == (1…10) #=> false
(1…10) == 5 #=> false
(1…10) === 5 #=> true

Since Ruby defines Range#=== to work the way it does, existing code
works with the definition.

Anyway, here’s the “proof”:

user system total real
unary unarray 5.050000 0.020000 5.070000 ( 5.182787)
.include? 3.560000 0.010000 3.570000 ( 3.629457)
override Array#=== 4.110000 0.010000 4.120000 ( 4.218315)

So if such code turns out to be a performance bottleneck in a
particular application, one approach at improving the performance
would be use include? in that case.

But I don’t think changing Array#=== is a good idea, nor even the best
solution to this particular performance problem. In fact it might be
fruitful to look at other approaches/algorithms such as testing with
regular expressions:

case word
when
/^(jan|febru)ary|ma(rch|y)|april|ju(ne|ly)|august|(octo|(sept|nov|dec)em)ber$/
‘month’
when /^(mon|(tu|wedn)es|thurs|fri|satur|sun)day$/
‘day’
else
‘neither’
end

With benchmarking to see if the ‘tuned’ regexps actually worked better
or worse than more straightforward ones. AND testing to make sure
that it really did what was expected.

Or hashes

WORD_MAP = Hash.new('neither).merge!({‘january’ => ‘month’, ‘february’
=> 'month, …
‘monday’ => ‘day’,
‘tuesday’ => ‘day’, … ‘sunday’ => ‘day’})
WORD_MAP[word]

with the proper substitution for the ellipses.

But the first test should be readability, and heroic efforts at
performance optimization should be left for truly deserving cases.

Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Wed, 24 Oct 2007 18:29:20 -0400 (EDT), David A. Black wrote:

*a = 1,2,3 means: assign to a that which, when unarrayed, is the
list 1,2,3 – namely, the array [1,2,3]. A stretch, perhaps, but it
sort of makes sense :slight_smile:

That makes a lot of sense! It’s similar to the way I taught myself how
to
deal with * in C, in a way that works both in declarations and code;
mentally, I call it “what’s at”. So

int i; /* i is an integer */
int ip; / what’s at ip is an integer */

ip = &i; /* set ip to the address of i */
ip = 3; / set what’s at ip to 3 */

That ends up explaining (nearly?) all the oddities of C declaration
syntax,
even function pointers.


Jay L. |
Boston, MA | My character doesn’t like it when they
Faster: jay at jay dot fm | cry or shout or hit.
http://www.jay.fm | - Kristoffer