Recommended
KEY
PDF
PDF
PDF
PDF
Ruby初級者向けレッスン 56回 ─── ブロック
PPS
PPT
Web2 Voorbeeldpresentatie
KEY
PDF
PDF
PDF
PPTX
Ruby enumerable source code reading
PDF
怠惰なRubyistへの道 fukuoka rubykaigi01
PDF
PDF
PDF
PDF
PDF
PPT
PDF
PDF
Ruby&Active Support for expert 3
PDF
Ruby初級者向けレッスン KOF2015 出張版
PDF
ODP
PPTX
PDF
Ruby初級者向けレッスン 50回 ─── ブロック
PPTX
PDF
What's Cooking In Ruby 2.7
More Related Content
KEY
PDF
PDF
PDF
PDF
Ruby初級者向けレッスン 56回 ─── ブロック
PPS
PPT
Web2 Voorbeeldpresentatie
KEY
Similar to Enumerable な何か、あるいは怠惰なる反復
PDF
PDF
PDF
PPTX
Ruby enumerable source code reading
PDF
怠惰なRubyistへの道 fukuoka rubykaigi01
PDF
PDF
PDF
PDF
PDF
PPT
PDF
PDF
Ruby&Active Support for expert 3
PDF
Ruby初級者向けレッスン KOF2015 出張版
PDF
ODP
PPTX
PDF
Ruby初級者向けレッスン 50回 ─── ブロック
PPTX
PDF
What's Cooking In Ruby 2.7
Enumerable な何か、あるいは怠惰なる反復 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. Class.constants
.map {|name| Class.const_get(name) }
.select {|obj| obj.is_a?(Class) }
.map {|clazz| clazz.ancestors }
.select {|classes|
classes.member?(Enumerable) }
.map(&:first)
25. 26. 27. 28. 29. 30. 31. 32. 33. 34. # e = [1,2,3].each
e.next
# => 1
35. # e = [1,2,3].each
e.next
e.next
# => 2
36. # e = [1,2,3].each
e.next
e.next
e.next
# => 3
37. # e = [1,2,3].each
e.next
e.next
e.next
e.next
# => StopIteration:
iteration reached an end
38. # e = [1,2,3].each
e.next
e.next
e.next
e.rewind
e.next
# => 1
39. 40. 41. 42. 43. 44. 45. 46. 47. 48. • コレクションを回す each は自分で頑張る
• ブロックを渡されない場合の each は
Enumerator を返す
• 他のメソッドは Enumerable にお任せ
49. 50. 1 class Directory
2 include Enumerable
3
4 def initialize(dirname)
5 @dirname = dirname
6 @files = Dir.open(dirname) {|dir|
7 dir.reject {|name| name == "." || name == ".." }
8 }
9 end
10
11 def each(&block)
12 if block_given?
13 @files.each do |name|
14 path = File.join(@dirname, name)
15 if File.directory?(path)
16 Directory.new(path).each(&block)
17 else
18 yield path
19 end
20 end
21 else
22 Enumerator.new(self, :each)
23 end
24
gist.github.com/3296137
end
25 end
51. 1 class Directory
2 include Enumerable
3
4 def initialize(dirname)
5 @dirname = dirname
6 @files = Dir.open(dirname) {|dir|
7 dir.reject {|name| name == "." || name == ".." }
8 }
9 end
10
11 def each(&block)
12 if block_given?
13 @files.each do |name|
14 path = File.join(@dirname, name)
15 if File.directory?(path)
16 Directory.new(path).each(&block)
17 else
18 yield path
19 end
20 end
21 else
22 Enumerator.new(self, :each)
23 end
24 end
25 end
52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. Editor's Notes #2 \n #3 \n #4 \n #5 \n #6 \n #7 \n #8 \n #9 \n #10 \n #11 \n #12 \n #13 \n #14 \n #15 \n #16 \n #17 \n #18 \n #19 いろんなやり方があるはず。\nここでは一例を。\n #20 ロードされているクラスのリストがほしい。\nクラスは定数でもあるから、そこから探してみる。\n\n #21 クラス名から、クラスの実体を取り出す方法\n #22 インスタンスが、あるクラス/モジュールに属しているかどうかを調べる\n #23 あるクラスの継承ツリーを調べる。\n先頭の要素が、該当クラス自身である点に注目。\n #24 \n #25 ここでターミナルに切り替えてデモ。\n #26 \n #27 \n #28 →ターミナルでデモ \nUser = Struct.new(:id, :name, :email)\nとかで例を見せる\n #29 ターミナルでデモ\nFile, Dir で例を見せる\n #30 Enumerable なクラスの特徴\nコレクションとは限らない\n #31 \n #32 \n #33 \n #34 each にブロックを渡さないところに注目\n(次以降に例が続く。まだターミナルに切り替えない)\n #35 \n #36 \n #37 \n #38 \n #39 巻戻しもできる\nここでターミナルに切替えてデモ\n #40 \n #41 Enumerator に対して #map を呼出す\nターミナルに切替えてデモ\n #42 \n #43 \n #44 \n #45 Array と Hash じゃ足りないこと、あるよね?\nツリー作るとか。\n #46 手間がかかりそうな予感。\nでも、やってみたら意外とシンプル。\n #47 Enumerable には #each は存在しない。\n(よく考えてみると当然。内部のデータ構造を知らないと each は書けない)\n #48 \n #49 場合によっては泥臭い処理を書かなきゃいけないかも。\n #50 \n #51 \n #52 コードを眺めながら解説\nその後、ターミナルに切替えて、実際の動きをデモ。\n #53 \n #54 \n #55 次の話題へ。\n #56 git 配下にはファイルがいっぱい。\nmap の後ろにはまだまだ処理が続くと思ってください。\n #57 \n #58 \n #59 名前の通り。\n #60 \n #61 \n #62 \n #63 \n #64 たとえば最初の要素を見ようとすると評価が走る。\n但し、2,3 については map されない。\n→ターミナルでデモ\n #65 \n #66 lazy 対応してやらなきゃダメ?\n #67 実装側には何も対応いらない。呼出し側で単に #lazy を最初に入れるだけ。\n→ターミナルに移動してデモ\n #68 \n #69 \n #70 \n #71 \n #72 \n #73 \n #74 \n #75 \n