One way I'm fond of is:
require 'generator'
enum = SyncEnumerator.new([1,2,3], [7,8,9])
enum.each do |pair|
puts pair.inspect
end
# Results in:
[1, 7]
[2, 8]
[3, 9]
···
On 3/6/06, Mark Watson <mark.watson@gmail.com> wrote:
If I have two containers c1 and c2 of the same length, what is the
proper "Ruby way" to do this:
c1.length.times {|i|
# access c1[i], c2[i]
}
I like that Ruby container classes provide their own iterators, but
what I would like to have is something like:
(c1,c2).each {|x1,x2| .... }
I thought of writing my own iterator class so that I could do something
like:
Iterator.new(c1,c2).each {|x1,x2| .... }
but that looks clumsy and inefficient.
I am transitioning to using mostly Ruby (moving away from Java, Lisp,
and Smalltalk) and I would like to use the proper Ruby idioms.
Warning, SyncEnumerator is slow, and you probably don't need it since #zip is in enumerable.
Run the below for a demonstration. Original I had it run each benchmark 10 times by the way, but I never had the patience to let the syncenum versions finish:
% cat zip_vs_syncenum.rb
require 'benchmark'
require 'generator'
a = (1..100)
b = a.to_a.reverse
puts "Using zip:"
Benchmark.bm { |x|
x.report {
3.times { a.zip(b) { |x, y| z = x * y } }
}
}
puts "Using SyncEnumerator(new every time):"
Benchmark.bm { |x|
x.report {
3.times {
a_b_enum = SyncEnumerator.new(a, b)
a_b_enum.each { |x, y| z = x * y }
}
}
}
puts "Using SyncEnumerator(only one created):"
Benchmark.bm { |x|
x.report {
a_b_enum = SyncEnumerator.new(a, b)
3.times { a_b_enum.each { |x, y| z = x * y } }
}
}
__END__
···
On Mar 6, 2006, at 5:17 PM, Wilson Bilkovich wrote:
One way I'm fond of is:
require 'generator'
enum = SyncEnumerator.new([1,2,3], [7,8,9])
enum.each do |pair|
puts pair.inspect
end
# Results in:
[1, 7]
[2, 8]
[3, 9]
> Mark Watson wrote:
>> If I have two containers c1 and c2 of the same length, what is the
>> proper "Ruby way" to do this:
>>
>> c1.length.times {|i|
>> # access c1[i], c2[i]
>> }
>>
>> I like that Ruby container classes provide their own iterators, but
>> what I would like to have is something like:
>>
>> (c1,c2).each {|x1,x2| .... }
>>
>> I thought of writing my own iterator class so that I could do something
>> like:
>>
>> Iterator.new(c1,c2).each {|x1,x2| .... }
>>
>> but that looks clumsy and inefficient.
>>
>> I am transitioning to using mostly Ruby (moving away from Java, Lisp,
>> and Smalltalk) and I would like to use the proper Ruby idioms.
>
> foo = %w(x y z) ; bar = [2,4,6]
> [foo, bar].transpose.each{|a,b| print a, b, $/ }
> --->
> x2
> y4
> z6
I don't think $/ is very idiomatic. See the ToDo file in the source;
it includes:
* discourage use of symbol variables (e.g. $/, etc.) in manual
David
idiomatic, adj. Peculiar to a particular group or individual.
"\n" is found in C and in awk, but $/ isn't; so it is more
nearly peculiar to Ruby. Some may lack the capacity to remember
what it represents.
However, I have no doubt that this is an unfashionable opinion
and that your view is the dominant one.
···
On Tue, 7 Mar 2006, William James wrote:
--
idiot, n. A member of a large and powerful tribe whose influence in
human affairs has always been dominant and controlling. ... He sets
the fashions of opinion and taste, dictates the limitations of speech,
and circumscribes conduct with a dead-line.
It was recently reworked to use threads instead of continuations, this resulted in a pretty significant speed boost. I doubt it beats Enumerable#zip yet, but the speed will be nice.
If I have two containers c1 and c2 of the same length, what is the
proper "Ruby way" to do this:
c1.length.times {|i|
# access c1[i], c2[i]
}
I like that Ruby container classes provide their own iterators, but
what I would like to have is something like:
(c1,c2).each {|x1,x2| .... }
I thought of writing my own iterator class so that I could do something
like:
Iterator.new(c1,c2).each {|x1,x2| .... }
but that looks clumsy and inefficient.
I am transitioning to using mostly Ruby (moving away from Java, Lisp,
and Smalltalk) and I would like to use the proper Ruby idioms.
foo = %w(x y z) ; bar = [2,4,6]
[foo, bar].transpose.each{|a,b| print a, b, $/ }
--->
x2
y4
z6
I don't think $/ is very idiomatic. See the ToDo file in the source;
it includes:
* discourage use of symbol variables (e.g. $/, etc.) in manual
David
idiomatic, adj. Peculiar to a particular group or individual.
"\n" is found in C and in awk, but $/ isn't; so it is more
nearly peculiar to Ruby. Some may lack the capacity to remember
what it represents.
However, I have no doubt that this is an unfashionable opinion
and that your view is the dominant one.
I share your opinion that $/ is not in C or awk, but is in Ruby
I'm thinking more about its position *within* Ruby, which isn't
directly connected to its presence or absence anywhere else. It's
there, but it seems to be in a bit of a shaky position.