Enumerable な採か、あるいは機区なる郡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(&:?rst)
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
48. ? コレクションを指す each は徭蛍でBる
? ブロックを局されない栽の each は
Enumerator を卦す
? 麿のメソッドは Enumerable にお販せ
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
Editor's Notes \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n いろんなやり方があるはず。\nここでは一例を。\n ロードされているクラスのリストがほしい。\nクラスは定数でもあるから、そこから探してみる。\n\n クラス名から、クラスの実体を取り出す方法\n インスタンスが、あるクラス/モジュールに属しているかどうかを調べる\n あるクラスの継承ツリーを調べる。\n先頭の要素が、該当クラス自身である点に注目。\n \n ここでターミナルに切り替えてデモ。\n \n \n →ターミナルでデモ \nUser = Struct.new(:id, :name, :email)\nとかで例を見せる\n ターミナルでデモ\nFile, Dir で例を見せる\n Enumerable なクラスの特徴\nコレクションとは限らない\n \n \n \n each にブロックを渡さないところに注目\n(次以降に例が続く。まだターミナルに切り替えない)\n \n \n \n \n 巻戻しもできる\nここでターミナルに切替えてデモ\n \n Enumerator に対して #map を呼出す\nターミナルに切替えてデモ\n \n \n \n Array と Hash じゃ足りないこと、あるよね?\nツリー作るとか。\n 手間がかかりそうな予感。\nでも、やってみたら意外とシンプル。\n Enumerable には #each は存在しない。\n(よく考えてみると当然。内部のデータ構造を知らないと each は書けない)\n \n 場合によっては泥臭い処理を書かなきゃいけないかも。\n \n \n コードを眺めながら解説\nその後、ターミナルに切替えて、実際の動きをデモ。\n \n \n 次の話題へ。\n git 配下にはファイルがいっぱい。\nmap の後ろにはまだまだ処理が続くと思ってください。\n \n \n 名前の通り。\n \n \n \n \n たとえば最初の要素を見ようとすると評価が走る。\n但し、2,3 については map されない。\n→ターミナルでデモ\n \n lazy 対応してやらなきゃダメ?\n 実装側には何も対応いらない。呼出し側で単に #lazy を最初に入れるだけ。\n→ターミナルに移動してデモ\n \n \n \n \n \n \n \n \n