I’m trying to backport my code from Ruby 1.9 to Ruby 1.8.7 so that I can
profile it sanely with ruby-prof or zenprofile (neither of which works
sensibly under Ruby 1.9 as of now). Unfortunately, my code heavily uses
lazy-evaluated, nested Enumerator objects. What is the sanest way to
backport the following example so that it works more-or-less in the same
way under Ruby 1.8.7 as it does under Ruby 1.9?
def multiplier param
Enumerator.new do |yielder|
(1..10).each do |elem|
sleep 1 # simulates a long-running process
yielder.yield param * elem
end
end
end
multiplier(3).each do |e|
puts e
end
I think I need a proxy object that can emulate Ruby 1.9’s Enumerator.new
by taking a block and then being able to evaluate it in the original
calling place’s context (so that the ‘param’ above is available to it
upon subsequent Enumerator#each calls), but my still-limited Ruby-fu
fails to come up with a solution for this.
— Shot
···
--
Local Man Plans To Run 3 Weeks’ Worth of Errands During
Twitter Maintenance Window [Patently False]
I’m trying to backport my code from Ruby 1.9 to Ruby 1.8.7 so that I can
profile it sanely with ruby-prof or zenprofile (neither of which works
sensibly under Ruby 1.9 as of now).
sensibly under Ruby 1.9 as of now). Unfortunately, my code heavily uses
lazy-evaluated, nested Enumerator objects. What is the sanest way to
backport the following example so that it works more-or-less in the same
way under Ruby 1.8.7 as it does under Ruby 1.9?
looks like there's a couple ways
one
require 'backports'
# leave the original code as is
or this one
require 'generator'
def multiplier param
Generator.new do |yielder|
(1..10).each do |elem|
sleep 1 # simulates a long-running process
yielder.yield param * elem
end
end
end
multiplier(3).each do |e|
puts e
end
I'm not sure if that will actually satisfy your desire (nor have I
figured out if enumerables are really "chainable" in 1.8 like they
apparently are in 1.9).
Thanks!
-r
I’m trying to backport my code from Ruby 1.9 to Ruby 1.8.7 so that I can
profile it sanely with ruby-prof or zenprofile (neither of which works
sensibly under Ruby 1.9 as of now).
ruby-prof does work in 1.9, there are even two versions that work.
Unfortunately, one of them does not aggregate the results (and
you end up with mutli-megabyte reports and thousands of calls like
Set#hash-1139), while the other, which does aggregate the results,
does this in insane amounts of time (I waited for an hour to get
a minute-long run results aggregated).
Unfortunately, my code heavily uses lazy-evaluated, nested Enumerator
objects. What is the sanest way to backport the following example
so that it works more-or-less in the same way under Ruby 1.8.7 as
it does under Ruby 1.9?
looks like there's a couple ways
one
require 'backports'
# leave the original code as is
Oh, wow! How could I have missed this? (Does not show up on ‘Ruby
backporting’ Google queries, but still…) This plus some amazingly
minimal monkey-patching got me a backport in two hours or so.
or this one
require 'generator'
def multiplier param
Generator.new do |yielder|
…AND I have missed Ruby 1.8’s stdlib’s Generator! A double shame,
but I’m happy as a clam nevertheless – I’ll finally be able to nicely
profile my PhD code!
(Even if the results do not necessarily reflect Ruby 1.9’s bottlenecks,
I guess they will be close enough, and being able to profile my code
will most probably turn the rest of the month into a very interesting
adventure with RuDy¹.)
Thanks a lot, James! As I just wrote in the reply to Roger Pack,
I ended up using the backports gem, and if I didn’t know about it
I’d most probably expose Generator.new as Enumerator.new, but the
closure and object examples are very enlightening.
Even more so is your ‘Higher-Order Ruby’ series, which I always split
into the ‘understandable’ part on Iterators, Caching and Memoization,
and the ‘still a bit over my head’ rest.
I think I’m finally ready to dive deep and wrap my
head around all of the concepts mentioned there.
— Shot
···
--
Blore’s Razor: Given a choice between two
theories, take the one which is funnier.