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 看 Ruby 的迭代器
Search
蒼時弦や
July 27, 2019
Programming
1
110
從 Enumerator 看 Ruby 的迭代器
RubyConf TW 2019
蒼時弦や
July 27, 2019
Tweet
Share
More Decks by 蒼時弦や
See All by 蒼時弦や
2024 - COSCUP - Clean Architecture in Rails
elct9620
2
160
2023 - RubyConfTW - Rethink Rails Architecture
elct9620
0
160
20230916 - DDDTW - 導入 Domain-Driven Design 的最佳時機
elct9620
0
420
2023 - WebConf - 選擇適合你的技能組合
elct9620
0
630
20230322 - Generative AI 小聚 ft. Happy Designer
elct9620
0
370
2022 - 默默會 - 重新學習 MVC 的 Model
elct9620
1
440
MOPCON 2022 - 從 Domain-Driven Design 看網站開發框架隱藏
elct9620
1
470
2022 - COSCUP - 我想慢慢寫程式該怎麼辦?
elct9620
0
250
2022 - COSCUP - 打造高速 Ruby 專案開發流程
elct9620
0
280
Other Decks in Programming
See All in Programming
“いい感じ“な定量評価を求めて - Four Keysとアウトカムの間の探求 -
nealle
2
10k
MDN Web Docs に日本語翻訳でコントリビュートしたくなる
ohmori_yusuke
1
130
チームで開発し事業を加速するための"良い"設計の考え方 @ サポーターズCoLab 2025-07-08
agatan
1
430
Flutterで備える!Accessibility Nutrition Labels完全ガイド
yuukiw00w
0
160
Node-RED を(HTTP で)つなげる MCP サーバーを作ってみた
highu
0
120
Webの外へ飛び出せ NativePHPが切り拓くPHPの未来
takuyakatsusa
2
560
イベントストーミング図からコードへの変換手順 / Procedure for Converting Event Storming Diagrams to Code
nrslib
2
850
PHPで始める振る舞い駆動開発(Behaviour-Driven Development)
ohmori_yusuke
2
400
プロダクト志向なエンジニアがもう一歩先の価値を目指すために意識したこと
nealle
0
130
Blazing Fast UI Development with Compose Hot Reload (droidcon New York 2025)
zsmb
1
300
ペアプロ × 生成AI 現場での実践と課題について / generative-ai-in-pair-programming
codmoninc
2
18k
Team operations that are not burdened by SRE
kazatohiei
1
310
Featured
See All Featured
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
6
310
KATA
mclloyd
30
14k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.4k
Making the Leap to Tech Lead
cromwellryan
134
9.4k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Agile that works and the tools we love
rasmusluckow
329
21k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
181
54k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
20k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
960
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
Transcript
Review Ruby s Iterator with Enumerator Photo by Tine Ivanič
on Unsplash
WEB DEVELOPER GAME DEVELOPER ࣌ ݭ @elct9620
None
As a Ruby developer, We use #each every day
BUT How it works?
#iterator Photo by Joel Fulgencio on Unsplash
def iterator(&block) yield 1 yield 2 yield 3 end
VALUE rb_block_call(VALUE obj, ID mid, int argc, const VALUE *
argv, VALUE (*bl_proc) (ANYARGS), VALUE data2) { struct iter_method_arg arg; arg.obj = obj; arg.mid = mid; arg.argc = argc; arg.argv = argv; return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2); } The block call is iterate in ruby
def each(&block) @i = 0 yield @i += 1 until
@i >= 10 end
#loop vs #while
static VALUE loop_i(void) { for (;;) { rb_yield_0(0, 0); }
return Qnil; } Loop is a method with a block
#enumerator Photo by Glenn Carstens-Peters on Unsplash
[].each # => #<Enumerator: []:each>
Why we need Enumerator?
enum = [1, 2, 3].to_enum enum.next # => 1 enum.next
# => 2 enum.next # => 3
Enumerator vs Enumerable
class Backpack include Enumerable def initialize(items) @items = items end
def each(&block) @items.each(&block) end end backpack = Backpack.new([:water, :apple]) backpack.map {}
#generator Photo by m0851 on Unsplash
#to_enum vs Enumerator.new
class List def each(&block) #... end end List.new.to_enum # =>
#<Enumerator: #<List:0x00007fa490988a78>:each>
class List def pop(&block) #... end end List.new.to_enum(:pop) # =>
#<Enumerator: #<List:0x00007fa491081fa0>:pop>
If Enumerator.new didn t have target ruby will create a
Generator
Enumerator.new do |yielder| yielder << 1 yielder << 2 end
Why we need Yielder?
enum = Enumerator.new do yield 1 yield 2 end puts
enum.to_a # => no block given (yield) (LocalJumpError)
class Yielder def initialize(&block) @proc = block.to_proc end def <<(value)
@proc.call(value) self end end
class Generator def initialize(&block) @proc = block.to_proc end def each(&_block)
yielder = Yielder.new { |x| yield x } @proc.call(yielder) end end
#lazy Photo by Kate Stone Matheson on Unsplash
It is hard to figure out it, but useful
class Backpack def each(&block) yield p(1) yield p(2) yield p(3)
end end backpack = Backpack.new.to_enum backpack.map(&:rect).take(1).to_a backpack.lazy.map(&:rect).take(1).to_a
class Backpack def each(&block) yield p(1) yield p(2) yield p(3)
end end backpack = Backpack.new.to_enum backpack.map(&:rect).take(1).to_a backpack.lazy.map(&:rect).take(1).to_a
backpack.map(&:rect).take(1).to_a # => 1 # => 2 # => 3
backpack.lazy.map(&:rect).take(1).to_a # => 1
backpack.take(1).to_a # => 1 backpack.lazy.take(1).to_a # => 1
backpack = Backpack.new.to_enum backpack.lazy.reverse_each.take(1).to_a # => 1 # => 2
# => 3
And last, let s discuss implement #lazy in Ruby
Thanks