On Tuesday 02 November 2004 02:31 am, Yukihiro Matsumoto wrote:
| Hi,
|
| In message "Re: require 'enumerator'"
|
|     on Tue, 2 Nov 2004 13:41:01 +0900, "trans.  (T. Onoma)" 
<transami / runbox.com> writes:
| |Is this right?
| |
| |irb(main):033:0> (1..10).enum_cons(2).to_a
| |=> [[9, 10], [9, 10], [9, 10], [9, 10], [9, 10], [9, 10], [9, 10], [9,
| | 10], [9, 10]]
|
| Here's the explanation:
|
| enum_cons() gathers values generated by each_cons().  each_cons()
| passes same array modifying for each time.  Thus all elements in the
| to_a array refers to the same array, thus it seems that all elements
| are [9,10].

I see.

| I'm not sure yet how it should behave.  Perhaps it should copy
| returning arrays somewhere.

I think something like that.
  
  a=[]; (1..10).enum_cons(2).each { |x| a << x }
  a=[]; (1..10).enum_cons(2).each { |x| a << x.dup }

Since these given completely different results.

But I have to tell you that I find Enumerator severely limited. To get an 
alternative iterative behavior, for instance, one has to provide the name of 
a method the defines the iteration. One barely needs an Enumerator object in 
that case, just call the method itself.

I guess what I'm getting at is that I'm not sure why Enumerator's slight bit 
of additional capability isn't just part of Enumerable itself. Is it that you 
have plans for making Enumerator more important in the future?


Also I would like to ouch on one other thing. I was thinking about the use of 
ranges in array indexes:

  a[1..3] 

That to me seems terribly inefficient since it has to create a whole new range 
first. I tend to go back and replace with:

  a[1,2]

It would be nice if one could still use from-to figures, but get the same 
efficiency/performance.

  require 'benchmark'
  $a = [ 'x' ] * 100
  $n = 500000

  def range_index
    i = 1
    $n.times { $a[1..i]; i += 1 }
  end

  def length_index
    i = 1
    $n.times { $a[1,i]; i += 1 }
  end

  Benchmark.bm(10) do |b|
    b.report("range_index:") { range_index }
    b.report("length_index:") { length_index }
  end

Results in:

                   user     system      total        real
   range_index:  2.300000   0.030000   2.330000 (  2.411080)
  length_index:  0.830000   0.050000   0.880000 (  0.914985)

One could of course create a separate method, but I wonder if you've ever 
considered argument capacity operators or method modifiers. For example, the 
',' itself would be just another capacity operator (the default), and one 
could define alternates, so for instance, one could separately define:

  def [](x:y)
  end

Only a few possibilities would really be needed. It could add a lot of 
flexability to the language.

Anyhow, just some food for thought.

T.