Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Enumerator::Lazy
Search
Erik Berlin
August 02, 2016
Programming
2
570
Enumerator::Lazy
Presented at SF.rb on August 2, 2016.
Erik Berlin
August 02, 2016
Tweet
Share
More Decks by Erik Berlin
See All by Erik Berlin
Ruby Trivia 3
sferik
0
700
The Value of Being Lazy
sferik
3
770
Ruby Trivia 2
sferik
0
750
Ruby Trivia
sferik
2
1.3k
💀 Symbols
sferik
5
1.9k
Content Negotiation for REST APIs
sferik
8
990
Writing Fast Ruby
sferik
628
62k
Mutation Testing with Mutant
sferik
5
1.1k
Other Decks in Programming
See All in Programming
PostgreSQLのRow Level SecurityをPHPのORMで扱う Eloquent vs Doctrine #phpcon #track2
77web
2
530
「テストは愚直&&網羅的に書くほどよい」という誤解 / Test Smarter, Not Harder
munetoshi
0
180
Hack Claude Code with Claude Code
choplin
4
2.2k
Flutterで備える!Accessibility Nutrition Labels完全ガイド
yuukiw00w
0
160
GitHub Copilot and GitHub Codespaces Hands-on
ymd65536
2
150
明示と暗黙 ー PHPとGoの インターフェイスの違いを知る
shimabox
2
520
Result型で“失敗”を型にするPHPコードの書き方
kajitack
5
920
Composerが「依存解決」のためにどんな工夫をしているか #phpcon
o0h
PRO
1
270
新メンバーも今日から大活躍!SREが支えるスケールし続ける組織のオンボーディング
honmarkhunt
5
7.6k
Goで作る、開発・CI環境
sin392
0
240
PipeCDのプラグイン化で目指すところ
warashi
1
280
地方に住むエンジニアの残酷な現実とキャリア論
ichimichi
5
1.6k
Featured
See All Featured
Code Review Best Practice
trishagee
69
19k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.4k
The Straight Up "How To Draw Better" Workshop
denniskardys
235
140k
RailsConf 2023
tenderlove
30
1.1k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Music & Morning Musume
bryan
46
6.6k
A designer walks into a library…
pauljervisheath
207
24k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
960
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
690
It's Worth the Effort
3n
185
28k
What's in a price? How to price your products and services
michaelherold
246
12k
Transcript
Enumerator::Lazy Erik Michaels-Ober @sferik
Imperative languages do iteration like this: int sum = 0;
for(i = 1; i < 10; i = i + 1) { sum = sum + i; }
Functional languages do iteration like this: rec_sum [] = 0
rec_sum (x:xs) = x + rec_sum xs rec_sum [1..9]
Object oriented languages (should) do iteration like this: sum =
0 (1..9).each do |i| sum += i end
Object oriented languages (should) do iteration like this: sum =
(1..9).inject(&:+)
Iterators Introduced in CLU by Barbara Liskov (1975) Copied in
Ruby by Yukihiro Matsumoto (1995)
Ruby’s iterator is called Enumerator
enum = Enumerator.new do |yielder| yielder.yield("sf") yielder.yield("dot") yielder.yield("rb") end
["sf", "dot", "rb"].each ["sf", "dot", "rb"].to_enum Enumerator.new(["sf", "dot", "rb"])
enum = Enumerator.new do |yielder| n = 0 loop do
yielder.yield(n) n += 1 end end
fib = Enumerator.new do |yielder| a = b = 1
loop do yielder.yield(a) a, b = b, a + b end end
module Enumerable def lazy_map(&block) Enumerator.new do |yielder| return to_enum(__method__) unless
block_given? each do |n| yielder.yield(block.call(n)) end end end end
module Enumerable def lazy_select(&block) Enumerator.new do |yielder| return to_enum(__method__) unless
block_given? each do |n| yielder.yield(n) if block.call(n) end end end end
Ruby 2.0 introduced Enumerator::Lazy
What are the first five even perfect squares over a
thousand?
lazy_integers = (1..Float::INFINITY).lazy lazy_integers.collect { |x| x ** 2 }.
select { |x| x.even? }. reject { |x| x < 1000 }. first(5) #=> [1024, 1156, 1296, 1444, 1600]
What are the first five twin primes?
require "prime" lazy_primes = Prime.lazy lazy_primes.select { |x| (x -
2).prime? }. collect { |x| [x - 2, x] }. first(5) #=> [[3, 5], [5, 7], [11, 13], [17, 19], [29, 31]]
module Enumerable def repeat_after_first return to_enum(__method__) unless block_given? each.with_index do
|*val, index| index.zero? ? yield(*val) : 2.times { yield(*val) } end end end
require "prime" lazy_primes = Prime.lazy lazy_primes.repeat_after_first. each_slice(2). select { |x,
y| x + 2 == y }. first(5) #=> [[3, 5], [5, 7], [11, 13], [17, 19], [29, 31]]
When are the next five Friday the 13ths?
require "date" lazy_dates = (Date.today..Date.new(9999)).lazy lazy_dates.select { |d| d.day ==
13 }. select { |d| d.friday? }. first(10)
Detect whether a text file contains a string? (without reading
the entire file into memory)
lazy_file = File.readlines("/path/to/file").lazy lazy_file.detect { |x| x =~ /regexp/ }
Being lazy is efficient.
Being lazy is elegant.
None
Thank you