Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
從 Enumerator 看 Ruby 的迭代器
蒼時弦や
July 27, 2019
Programming
1
50
從 Enumerator 看 Ruby 的迭代器
RubyConf TW 2019
蒼時弦や
July 27, 2019
Tweet
Share
More Decks by 蒼時弦や
See All by 蒼時弦や
2021 - RubyKaigi - It is time to build your mruby VM on the microcontroller?
elct9620
0
21
2021 - TGDF - Unlight 從 TCP 到 WebSocket 的 HTML5 之路
elct9620
0
56
2020 - MOPCON - 拿到錘子的我想在為控制器上實作 Ruby VM
elct9620
0
59
2020 - COSCUP - 你這段 Ruby Code 超速摟,已經沒有人看得懂了!
elct9620
0
66
2019 - PVE 社群 - Rails 串接 Proxmox VE API 自動化教學用虛擬機分配
elct9620
1
480
2019 - COSCUP - 復活一個 Browser Game - Unlight 開源事件
elct9620
1
350
從學校到業界,工程師作為職業的現實
elct9620
0
55
2018 - COSCUP - 來做一個日系卡牌手遊吧!
elct9620
0
180
2018 - How the Rubyist use Blockchain
elct9620
0
65
Other Decks in Programming
See All in Programming
From Java through Scala to Clojure
lagenorhynque
0
190
Reactive Java Microservices on Kubernetes with Spring and JHipster
deepu105
1
170
インターン生・新卒向け、学校でもっと教えてほしいITエンジニア基本スキル
nearme_tech
0
120
Java アプリとAWS の良い関係 - AWS でJava アプリを実行する一番簡単な方法教えます / AWS for Javarista
kanamasa
2
1.2k
iOS 16からのロック画面Widget争奪戦に備える
tsuzuki817
0
210
The strategies behind ddd – AdeoDevSummit 2022
lilobase
PRO
4
240
#JJUG_CCC 「サポート」は製品開発? - JDBCライブラリ屋さんが実践する攻めのテクニカルサポートとJavaエンジニアのキャリアについて -
cdataj
0
420
engineer
spacemarket
0
870
[월간 데이터리안 세미나 6월] 스스로 성장하는 분석가 커리어 이야기
datarian
0
180
ドメインモデル方式のクラス設計 座談会
masuda220
PRO
3
1k
Jetpack Compose, 어디까지 알고 있을까?
jisungbin
0
110
Beyond Micro Frontends: Frontend Moduliths for the Enterprise @enterjs2022
manfredsteyer
PRO
0
150
Featured
See All Featured
Teambox: Starting and Learning
jrom
123
7.7k
GraphQLの誤解/rethinking-graphql
sonatard
27
6.6k
4 Signs Your Business is Dying
shpigford
169
20k
Why You Should Never Use an ORM
jnunemaker
PRO
47
7.6k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
351
21k
Building Applications with DynamoDB
mza
83
4.7k
JazzCon 2018 Closing Keynote - Leadership for the Reluctant Leader
reverentgeek
172
8.4k
Build your cross-platform service in a week with App Engine
jlugia
219
17k
Product Roadmaps are Hard
iamctodd
34
6.5k
We Have a Design System, Now What?
morganepeng
35
3k
Principles of Awesome APIs and How to Build Them.
keavy
113
15k
Learning to Love Humans: Emotional Interface Design
aarron
261
37k
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