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
95
從 Enumerator 看 Ruby 的迭代器
RubyConf TW 2019
蒼時弦や
July 27, 2019
Tweet
Share
More Decks by 蒼時弦や
See All by 蒼時弦や
2023 - RubyConfTW - Rethink Rails Architecture
elct9620
0
62
20230916 - DDDTW - 導入 Domain-Driven Design 的最佳時機
elct9620
0
320
2023 - WebConf - 選擇適合你的技能組合
elct9620
0
520
20230322 - Generative AI 小聚 ft. Happy Designer
elct9620
0
260
2022 - 默默會 - 重新學習 MVC 的 Model
elct9620
1
380
MOPCON 2022 - 從 Domain-Driven Design 看網站開發框架隱藏
elct9620
1
410
2022 - COSCUP - 我想慢慢寫程式該怎麼辦?
elct9620
0
210
2022 - COSCUP - 打造高速 Ruby 專案開發流程
elct9620
0
230
2021 - RubyKaigi - It is time to build your mruby VM on the microcontroller?
elct9620
0
190
Other Decks in Programming
See All in Programming
CSC307 Lecture 14
javiergs
PRO
0
220
最近追加した型の紹介とその振り返り
aki19035vc
0
170
AHC035解説
terryu16
0
710
Polarsの成長: v0.14からv1.0までの変遷と今後の展望
zerebom
1
350
【Go言語】golangci-lintの使い方
tomo1227
0
270
Clean Architecture by TypeScript & NestJS
ryounasso
0
150
OpenAI/Gemini APIを使って EPUBを翻訳するCLIツールをつくってみた
tomiyan
0
790
Prompt FlowによるLLMアプリケーション開発
yuto2000
1
1k
TiDB Serverless ~理想のServerless DBを考える~
soso_15315
1
160
Advanced App Shrinking Techniques
cbeyls
2
150
CSC307 Lecture 11
javiergs
PRO
0
240
Ruby メモリ管理 プログラミング
megmogmog1965
0
130
Featured
See All Featured
Pencils Down: Stop Designing & Start Developing
hursman
118
11k
Build your cross-platform service in a week with App Engine
jlugia
227
17k
[RailsConf 2023] Rails as a piece of cake
palkan
35
4.4k
Visualization
eitanlees
139
14k
VelocityConf: Rendering Performance Case Studies
addyosmani
321
23k
Documentation Writing (for coders)
carmenintech
63
4.2k
Rails Girls Zürich Keynote
gr2m
93
13k
Building Your Own Lightsaber
phodgson
101
5.9k
Optimising Largest Contentful Paint
csswizardry
18
2.6k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
226
52k
How to Ace a Technical Interview
jacobian
274
23k
10 Git Anti Patterns You Should be Aware of
lemiorhan
652
58k
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