Case

Hi

a=3
p case a
  when 0 then 0
  when 1 then 1
  when 2 then 2
  when 3, a>5 then 3
  else 99
end

Seems you can't combine values and statements (a>5).
How can I write that, if I have additional statements (in some cases), but would like to use "values only" for most of the cases?

Thanks
Opti

There's no such thing as a statement in Ruby.

···

On Tue, Jan 10, 2017 at 4:16 PM, Die Optimisten <inform@die-optimisten.net> wrote:

Seems you can't combine values and statements (a>5).

--
        Eric Christopherson

You can use a lambda if you like:

irb(main):032:0> (0..10).each do |a|
irb(main):033:1* p case a
irb(main):034:2> when 0 then 0
irb(main):035:2> when 1 then 1
irb(main):036:2> when 2 then 2
irb(main):037:2> when -> (x) { x == 3 || x > 5 } then 3
irb(main):038:2> else 99
irb(main):039:2> end
irb(main):040:1> end
0
1
2
3
99
99
3
3
3
3
3
=> 0..10

Hope this helps,

Mike

···

On Jan 10, 2017, at 5:16 PM, Die Optimisten <inform@die-optimisten.net> wrote:

Hi

a=3
p case a
when 0 then 0
when 1 then 1
when 2 then 2
when 3, a>5 then 3
else 99
end

Seems you can't combine values and statements (a>5).
How can I write that, if I have additional statements (in some cases), but would like to use "values only" for most of the cases?

Thanks
Opti

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--

Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.

a=3
p case a
when 0 then 0
when 1 then 1
when 2 then 2
when 3, a>5 then 3
else 99
end

a=3
p case a
  when 0 then 0
  when 1 then 1
  when 2 then 2
  when 4..5 then 99 # using a range here to cover your original 'else'
clause
  else 3 # this is now 'when 3, a > 5'
end

And the generic answer for arbitrary conditions is: use a lambda,
because my suggestion to make lambda support #=== as an alias for
#call and # was implemented a long time ago:

irb(main):002:0> x = lambda {|a| a > 5}
=> #<Proc:0x00000001287250@(irb):2 (lambda)>
irb(main):003:0> 10.times {|i| printf "%2d -> %p\n", i, x === i}
0 -> false
1 -> false
2 -> false
3 -> false
4 -> false
5 -> false
6 -> true
7 -> true
8 -> true
9 -> true
=> 10

Equipped with the knowledge that case uses === for matching you can
easily use that here:

LARGER_THAN_5 = lambda {|n| n > 5}

a=3
p case a
when 0 then 0
when 1 then 1
when 2 then 2
when 3, LARGER_THAN_5 then 3
else 99
end

Note, you can rewrite that to

a = 3
p case a
when 0,1,2,3 then a
when LARGER_THAN_5 then 3
else 99
end

or use a Hash or ...

irb(main):047:0> FIXED = {0=>0,1=>1,2=>2,3=>3}
irb(main):048:0> -3.upto(10) {|i| printf "%2d -> %p\n", i,
FIXED.fetch(i) { i>5 ? 3 : 99 }}
-3 -> 99
-2 -> 99
-1 -> 99
0 -> 0
1 -> 1
2 -> 2
3 -> 3
4 -> 99
5 -> 99
6 -> 3
7 -> 3
8 -> 3
9 -> 3
10 -> 3
=> -3

etc.

Cheers

robert

···

On Wed, Jan 11, 2017 at 12:10 AM, James Pacheco <james.pacheco@gmail.com> wrote:

a=3
p case a
when 0 then 0
when 1 then 1
when 2 then 2
when 3, a>5 then 3
else 99
end

a=3
p case a
  when 0 then 0
  when 1 then 1
  when 2 then 2
  when 4..5 then 99 # using a range here to cover your original 'else'
clause
  else 3 # this is now 'when 3, a > 5'
end

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

p case a
when 0 then 0
when 1 then 1
when 2 then 2
when 3, a>5 then 3
else 99
end

try the else part,

p case a
when 0 then 0
when 1 then 1
when 2 then 2
when 3 then 3
else
  if a > 5
     3
  else
     99
  end
end

you can replace the if with another (nested) case if you're fond of case : )

Seems you can't combine values and statements (a>5)

try the other case and other combinations case w case, case w if, etc,

p case
when [0,1,2,3].include?(a)
   a
when a > 5
     3
else
     99
end

kind regards
--botp

···

On Wed, Jan 11, 2017 at 6:16 AM, Die Optimisten <inform@die-optimisten.net> wrote:

And the generic answer for arbitrary conditions is: use a lambda,
because my suggestion to make lambda support #=== as an alias for
#call and # was implemented a long time ago:

As the great Alan Perlis didn't quite say:

[Ruby] programmers know the value of everything and the cost of nothing.

Generic answers are great for generic questions, but using a proc in this case (no pun intended) comes with a very large cost. I really liked James' suggestion, to flip the logic around, but I knew that the range was

What I'm truly surprised by is James' solution being as slow as it was. I figured it had to beat out proc activation. I'm also a bit surprised at the cost of my valueless case (ryan2).

---- benchmark and results follow

require 'benchmark/ips'

LARGER_THAN_5 = lambda { |m| m > 5}

def robert n
  case n
  when 0 then 0
  when 1 then 1
  when 2 then 2
  when 3, LARGER_THAN_5 then 3
  else 99
  end
end

def robert2 n
  case n
  when 0,1,2,3 then n
  when LARGER_THAN_5 then 3
  else 99
  end
end

def mike n
  case n
  when 0 then 0
  when 1 then 1
  when 2 then 2
  when -> (x) { x == 3 || x > 5 } then 3
  else 99
  end
end

def james n
  case n
  when 0 then 0
  when 1 then 1
  when 2 then 2
  when 4..5 then 99 # using a range here to cover your original 'else' clause
  else 3 # this is now 'when 3, a > 5'
  end
end

def ryan n
  case n
  when 0 then 0
  when 1 then 1
  when 2 then 2
  when 4, 5 then 99 # because range will bite you
  else 3
  end
end

def ryan2 n
  case
  when n==0 then 0
  when n==1 then 1
  when n==2 then 2
  when n==3 || n>5 then 3 # just to see the impact of a valueless case
  else 99
  end
end

10.times do |n|
  v0, v1, v2, v3, v4, v5 =
    robert(n), robert2(n), mike(n), james(n), ryan(n), ryan2(n)

  abort "bad" if [v0, v1, v2, v3, v4, v5].uniq.size != 1
end

Benchmark.ips do |x|
  x.report("robert") do |t| t.times do 10.times do |n| robert n end end end
  x.report("robert2") do |t| t.times do 10.times do |n| robert2 n end end end
  x.report("james") do |t| t.times do 10.times do |n| james n end end end
  x.report("mike") do |t| t.times do 10.times do |n| mike n end end end
  x.report("ryan") do |t| t.times do 10.times do |n| ryan n end end end
  x.report("ryan2") do |t| t.times do 10.times do |n| ryan2 n end end end

  x.compare!
end

# Calculating -------------------------------------
# robert 278.388k (+/- 2.8%) i/s - 1.408M in 5.059990s
# robert2 283.350k (+/- 2.4%) i/s - 1.425M in 5.031756s
# james 264.979k (+/- 3.3%) i/s - 1.344M in 5.079088s
# mike 139.618k (+/- 3.8%) i/s - 701.028k in 5.029633s
# ryan 849.322k (+/- 3.0%) i/s - 4.300M in 5.067430s
# ryan2 640.050k (+/- 2.5%) i/s - 3.209M in 5.016532s

···

On Jan 11, 2017, at 03:27, Robert Klemme <shortcutter@googlemail.com> wrote:

#
# Comparison:
# ryan: 849322.2 i/s
# ryan2: 640050.3 i/s - 1.33x slower
# robert2: 283349.9 i/s - 3.00x slower
# robert: 278387.7 i/s - 3.05x slower
# james: 264979.4 i/s - 3.21x slower
# mike: 139618.4 i/s - 6.08x slower

First time I hear about that alias.
Just awesome! Thank you very much.

···

On Wed, 11 Jan 2017 at 11:27, Robert Klemme <shortcutter@googlemail.com> wrote:

On Wed, Jan 11, 2017 at 12:10 AM, James Pacheco <james.pacheco@gmail.com> > wrote:

>> a=3

>> p case a

>> when 0 then 0

>> when 1 then 1

>> when 2 then 2

>> when 3, a>5 then 3

>> else 99

>> end

>

> a=3

> p case a

> when 0 then 0

> when 1 then 1

> when 2 then 2

> when 4..5 then 99 # using a range here to cover your original 'else'

> clause

> else 3 # this is now 'when 3, a > 5'

> end

And the generic answer for arbitrary conditions is: use a lambda,

because my suggestion to make lambda support #=== as an alias for

#call and # was implemented a long time ago:

irb(main):002:0> x = lambda {|a| a > 5}

=> #<Proc:0x00000001287250@(irb):2 (lambda)>

irb(main):003:0> 10.times {|i| printf "%2d -> %p\n", i, x === i}

0 -> false

1 -> false

2 -> false

3 -> false

4 -> false

5 -> false

6 -> true

7 -> true

8 -> true

9 -> true

=> 10

Equipped with the knowledge that case uses === for matching you can

easily use that here:

LARGER_THAN_5 = lambda {|n| n > 5}

a=3

p case a

when 0 then 0

when 1 then 1

when 2 then 2

when 3, LARGER_THAN_5 then 3

else 99

end

Note, you can rewrite that to

a = 3

p case a

when 0,1,2,3 then a

when LARGER_THAN_5 then 3

else 99

end

or use a Hash or ...

irb(main):047:0> FIXED = {0=>0,1=>1,2=>2,3=>3}

irb(main):048:0> -3.upto(10) {|i| printf "%2d -> %p\n", i,

FIXED.fetch(i) { i>5 ? 3 : 99 }}

-3 -> 99

-2 -> 99

-1 -> 99

0 -> 0

1 -> 1

2 -> 2

3 -> 3

4 -> 99

5 -> 99

6 -> 3

7 -> 3

8 -> 3

9 -> 3

10 -> 3

=> -3

etc.

Cheers

robert

--

[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can

- without end}

http://blog.rubybestpractices.com/

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

That is so cool Robert!

Thanks for the insight Ryan. I was expecting that. It doesn't take the
value out of the === alias tough.
Although I must admite it may decrease code readability. It needs to be
used in a wise way.

···

On Wed, 11 Jan 2017 at 12:30, Ryan Davis <ryand-ruby@zenspider.com> wrote:

> On Jan 11, 2017, at 03:27, Robert Klemme <shortcutter@googlemail.com> > wrote:

>

> And the generic answer for arbitrary conditions is: use a lambda,

> because my suggestion to make lambda support #=== as an alias for

> #call and # was implemented a long time ago:

As the great Alan Perlis didn't quite say:

> [Ruby] programmers know the value of everything and the cost of nothing.

Generic answers are great for generic questions, but using a proc in this
case (no pun intended) comes with a very large cost. I really liked James'
suggestion, to flip the logic around, but I knew that the range was

What I'm truly surprised by is James' solution being as slow as it was. I
figured it had to beat out proc activation. I'm also a bit surprised at the
cost of my valueless case (ryan2).

---- benchmark and results follow

require 'benchmark/ips'

LARGER_THAN_5 = lambda { |m| m > 5}

def robert n

  case n

  when 0 then 0

  when 1 then 1

  when 2 then 2

  when 3, LARGER_THAN_5 then 3

  else 99

  end

end

def robert2 n

  case n

  when 0,1,2,3 then n

  when LARGER_THAN_5 then 3

  else 99

  end

end

def mike n

  case n

  when 0 then 0

  when 1 then 1

  when 2 then 2

  when -> (x) { x == 3 || x > 5 } then 3

  else 99

  end

end

def james n

  case n

  when 0 then 0

  when 1 then 1

  when 2 then 2

  when 4..5 then 99 # using a range here to cover your original 'else'
clause

  else 3 # this is now 'when 3, a > 5'

  end

end

def ryan n

  case n

  when 0 then 0

  when 1 then 1

  when 2 then 2

  when 4, 5 then 99 # because range will bite you

  else 3

  end

end

def ryan2 n

  case

  when n==0 then 0

  when n==1 then 1

  when n==2 then 2

  when n==3 || n>5 then 3 # just to see the impact of a valueless case

  else 99

  end

end

10.times do |n|

  v0, v1, v2, v3, v4, v5 =

    robert(n), robert2(n), mike(n), james(n), ryan(n), ryan2(n)

  abort "bad" if [v0, v1, v2, v3, v4, v5].uniq.size != 1

end

Benchmark.ips do |x|

  x.report("robert") do |t| t.times do 10.times do |n| robert n end end
end

  x.report("robert2") do |t| t.times do 10.times do |n| robert2 n end end
end

  x.report("james") do |t| t.times do 10.times do |n| james n end end
end

  x.report("mike") do |t| t.times do 10.times do |n| mike n end end
end

  x.report("ryan") do |t| t.times do 10.times do |n| ryan n end end
end

  x.report("ryan2") do |t| t.times do 10.times do |n| ryan2 n end end
end

  x.compare!

end

# Calculating -------------------------------------

# robert 278.388k (+/- 2.8%) i/s - 1.408M in
5.059990s

# robert2 283.350k (+/- 2.4%) i/s - 1.425M in
5.031756s

# james 264.979k (+/- 3.3%) i/s - 1.344M in
5.079088s

# mike 139.618k (+/- 3.8%) i/s - 701.028k in
5.029633s

# ryan 849.322k (+/- 3.0%) i/s - 4.300M in
5.067430s

# ryan2 640.050k (+/- 2.5%) i/s - 3.209M in
5.016532s

#

# Comparison:

# ryan: 849322.2 i/s

# ryan2: 640050.3 i/s - 1.33x slower

# robert2: 283349.9 i/s - 3.00x slower

# robert: 278387.7 i/s - 3.05x slower

# james: 264979.4 i/s - 3.21x slower

# mike: 139618.4 i/s - 6.08x slower

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

> p case a

> when 0 then 0

> when 1 then 1

> when 2 then 2

> when 3, a>5 then 3

> else 99

> end

try the else part,

p case a

when 0 then 0

when 1 then 1

when 2 then 2

when 3 then 3

else

  if a > 5

     3

  else

     99

  end

end

you can replace the if with another (nested) case if you're fond of case :
)

> Seems you can't combine values and statements (a>5)

try the other case and other combinations case w case, case w if, etc,

p case

when [0,1,2,3].include?(a)

What about: (0..3).include?(a)

   a

when a > 5

     3

else

     99

end

kind regards

--botp

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

···

On Wed, 11 Jan 2017 at 13:07, botp <botpena@gmail.com> wrote:

On Wed, Jan 11, 2017 at 6:16 AM, Die Optimisten > > <inform@die-optimisten.net> wrote:

And the generic answer for arbitrary conditions is: use a lambda,
because my suggestion to make lambda support #=== as an alias for
#call and # was implemented a long time ago:

As the great Alan Perlis didn't quite say:

[Ruby] programmers know the value of everything and the cost of nothing.

Generic answers are great for generic questions, but using a proc in this case (no pun intended) comes with a very large cost. I really liked James' suggestion, to flip the logic around, but I knew that the range was

I wasn't suggesting to use the lambda here - I was just using this
case for illustration. For other cases you can actually create pretty
readable code with this pattern.

What I'm truly surprised by is James' solution being as slow as it was. I figured it had to beat out proc activation. I'm also a bit surprised at the cost of my valueless case (ryan2).

I believe James' solution creates a new Range instance during every
iteration (unless there is some optimization going un underneath like
for Regex) so you could try with the range in a constant.

Kind regards

robert

···

On Wed, Jan 11, 2017 at 1:30 PM, Ryan Davis <ryand-ruby@zenspider.com> wrote:

On Jan 11, 2017, at 03:27, Robert Klemme <shortcutter@googlemail.com> wrote:

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

What I'm truly surprised by is James' solution being as slow as it was. I figured it had to beat out proc activation. I'm also a bit surprised at the cost of my valueless case (ryan2).

<snip>

def ryan n
  case n
  when 0 then 0
  when 1 then 1
  when 2 then 2
  when 4, 5 then 99 # because range will bite you
  else 3
  end
end

All literals for "when" means MRI/YARV optimizes the above to a
hash table internally ("opt_case_dispatch" in compile.c and insns.def)

def ryan2 n
  case
  when n==0 then 0
  when n==1 then 1
  when n==2 then 2
  when n==3 || n>5 then 3 # just to see the impact of a valueless case
  else 99
  end
end

No optimized dispatch, above, since it's all variable.

···

Ryan Davis <ryand-ruby@zenspider.com> wrote:

# Calculating -------------------------------------
# robert 278.388k (+/- 2.8%) i/s - 1.408M in 5.059990s
# robert2 283.350k (+/- 2.4%) i/s - 1.425M in 5.031756s
# james 264.979k (+/- 3.3%) i/s - 1.344M in 5.079088s
# mike 139.618k (+/- 3.8%) i/s - 701.028k in 5.029633s
# ryan 849.322k (+/- 3.0%) i/s - 4.300M in 5.067430s
# ryan2 640.050k (+/- 2.5%) i/s - 3.209M in 5.016532s
#
# Comparison:
# ryan: 849322.2 i/s
# ryan2: 640050.3 i/s - 1.33x slower
# robert2: 283349.9 i/s - 3.00x slower
# robert: 278387.7 i/s - 3.05x slower
# james: 264979.4 i/s - 3.21x slower
# mike: 139618.4 i/s - 6.08x slower

(0..3) is a range. it will include any numbers (including fractions etc) in bw

(0..3).include? 1.5
=> true

kind regards
--botp

···

On Wed, Jan 11, 2017 at 9:22 PM, Daniel Ferreira <subtileos@gmail.com> wrote:

What about: (0..3).include?(a)

It's because (a..b).include?(n) checks if n >= a && n <= b. It does not
check if the value is actually inside of the range.

···

On Wed, Jan 11, 2017 at 9:43 AM, botp <botpena@gmail.com> wrote:

On Wed, Jan 11, 2017 at 9:22 PM, Daniel Ferreira <subtileos@gmail.com> > wrote:
>> What about: (0..3).include?(a)

(0..3) is a range. it will include any numbers (including fractions etc)
in bw

(0..3).include? 1.5
=> true

kind regards
--botp

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

That is surprising.
I had this behaviour in my mind:

(0..3).each { |i| puts I }
0
1
2
3

Different behaviours?

···

On Wed, 11 Jan 2017 at 14:47, Eli Sadoff <snood1205@gmail.com> wrote:

It's because (a..b).include?(n) checks if n >= a && n <= b. It does not
check if the value is actually inside of the range.

On Wed, Jan 11, 2017 at 9:43 AM, botp <botpena@gmail.com> wrote:

On Wed, Jan 11, 2017 at 9:22 PM, Daniel Ferreira <subtileos@gmail.com> > wrote:

>> What about: (0..3).include?(a)

(0..3) is a range. it will include any numbers (including fractions etc)
in bw

(0..3).include? 1.5

=> true

kind regards

--botp

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

That is surprising.
I had this behaviour in my mind:

(0..3).each { |i| puts I }
0
1
2
3

Sorry about the typo.

What about the behaviour:
> (0..3).to_a
=> [0, 1, 2, 3]
Different behaviours?

It's because (a..b).include?(n) checks if n >= a && n <= b. It does not
check if the value is actually inside of the range.

>> What about: (0..3).include?(a)

(0..3) is a range. it will include any numbers (including fractions etc)
in bw

(0..3).include? 1.5

=> true

kind regards

--botp

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

···

On Wed, 11 Jan 2017 at 15:11, Daniel Ferreira <subtileos@gmail.com> wrote:

On Wed, 11 Jan 2017 at 14:47, Eli Sadoff <snood1205@gmail.com> wrote:
On Wed, Jan 11, 2017 at 9:43 AM, botp <botpena@gmail.com> wrote:
On Wed, Jan 11, 2017 at 9:22 PM, Daniel Ferreira <subtileos@gmail.com> > wrote:

That is surprising.
I had this behaviour in my mind:

(0..3).each { |i| puts I }
0
1
2
3

Sorry about the typo.

What about the behaviour:
> (0..3).to_a
=> [0, 1, 2, 3]

Different behaviours?

Also documentation neglects completely that behaviour. A reader will
hardly get it.
I believe we should update Range#include? documentation with those
particular situations.
Are there unit tests for that as well?

It's because (a..b).include?(n) checks if n >= a && n <= b. It does not
check if the value is actually inside of the range.

>> What about: (0..3).include?(a)

(0..3) is a range. it will include any numbers (including fractions etc)
in bw

(0..3).include? 1.5

=> true

kind regards

--botp

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

···

On Wed, 11 Jan 2017 at 15:13, Daniel Ferreira <subtileos@gmail.com> wrote:

On Wed, 11 Jan 2017 at 15:11, Daniel Ferreira <subtileos@gmail.com> wrote:
On Wed, 11 Jan 2017 at 14:47, Eli Sadoff <snood1205@gmail.com> wrote:
On Wed, Jan 11, 2017 at 9:43 AM, botp <botpena@gmail.com> wrote:
On Wed, Jan 11, 2017 at 9:22 PM, Daniel Ferreira <subtileos@gmail.com> > wrote:

Hi all!
Thanks for all these many helpful answers,
- in 2 days as much conversation as in many months!!
...don't know when I'm through with all!

Opti :))

(0..3).each { |i| puts I }
0
1
2
3

What about the behaviour:
> (0..3).to_a
=> [0, 1, 2, 3]

ruby tries very hard to iterate as much as it can. you would not want
it to spit out all/infinite numbers.
eg, if you feed a float for the first obj of the range, ruby will raise,

(1.0 .. 3).each{|x| p x}

TypeError: can't iterate from Float

if the only the last obj is float, ruby will try to be friendly again.
eg

(0 .. 3.5).each{|x| p x}

0
1
2
3

you can also try the #step method.
eg

(1.1 .. 2.03).step(0.1).to_a

=> [1.1, 1.2000000000000002, 1.3, 1.4000000000000001, 1.5, 1.6,
1.7000000000000002, 1.8000000000000003, 1.9000000000000001, 2.0]

again, ruby just trying to help programmer.

kind regards
--botp

···

On Wed, Jan 11, 2017 at 11:13 PM, Daniel Ferreira <subtileos@gmail.com> wrote:

On the whole if the behavior of something seems surprising, it is either
likely documented or is definitely in the source code.

···

On Wed, Jan 11, 2017 at 12:11 PM, botp <botpena@gmail.com> wrote:

On Wed, Jan 11, 2017 at 11:13 PM, Daniel Ferreira <subtileos@gmail.com> > wrote:
>> (0..3).each { |i| puts I }
>> 0
>> 1
>> 2
>> 3

>> What about the behaviour:
>> > (0..3).to_a
>> => [0, 1, 2, 3]

ruby tries very hard to iterate as much as it can. you would not want
it to spit out all/infinite numbers.
eg, if you feed a float for the first obj of the range, ruby will raise,

> (1.0 .. 3).each{|x| p x}
TypeError: can't iterate from Float

if the only the last obj is float, ruby will try to be friendly again.
eg

> (0 .. 3.5).each{|x| p x}
0
1
2
3

you can also try the #step method.
eg

> (1.1 .. 2.03).step(0.1).to_a
=> [1.1, 1.2000000000000002, 1.3, 1.4000000000000001, 1.5, 1.6,
1.7000000000000002, 1.8000000000000003, 1.9000000000000001, 2.0]

again, ruby just trying to help programmer.

kind regards
--botp

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;