「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
Rubyでとりあえず書く
def get_room_list_from_blocks
if self.blocks.nil?
return []
elsif self.blocks.size <= 0
return []
else
ret = []
for i in (0..self.blocks.size)
rooms = self.blocks[i].rooms
if rooms.size > 0
for j in (0..rooms.size)
ret << b.rooms[j]
end
end
end
return ret
end
end
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
ガード条件は後置構文ですっき
り
def get_room_list_from_blocks
return [] if (self.blocks || []).empty?
ret = []
for i in (0..self.blocks.size)
rooms = self.blocks[i].rooms
for j in (0..rooms.size)
ret << b.rooms[j]
end
end
return ret
end
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
"for"を"each"に変えよう
def get_room_list_from_blocks
return [] if (self.blocks || []).empty?
ret = []
self.blocks.each do |b|
rooms = b.rooms
unless rooms.empty?
rooms.each do |r|
ret << r
end
end
end
return ret
end
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
blockはroomsを持っている
か知っているよね?
class Block
# ...
def has_rooms?
self.rooms.empty? ? false : true
end
# ...
end
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
"roomsを持っているblockを
選ぶ"ようにしましょう
def get_room_list_from_blocks
return [] if (self.blocks || []).empty?
ret = []
bs = self.blocks.select(&:has_rooms?)
bs.each do |b|
b.rooms.each{|r| ret << r}
end
return ret
end
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
リストを処理するメソッドにはこ
んなものも
collect : リストから評価した値を
集める
個人的にはmapをよく使う
flatten : リストを平坦にする
[1, [2,3], [4, [5,6]]].flatten =>
[1,2,3,4,5,6]
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
"collect"や"flatten"も使い
ましょう
def get_room_list_from_blocks
return [] if (self.blocks || []).empty?
ret = self.blocks.select(&:has_rooms?).collect(&:rooms).flatten
return ret
end
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
Rubyは「最後に評価した値を
返す」のでreturnいりません
def get_room_list_from_blocks
return [] if (self.blocks || []).empty?
self.blocks.select(&:has_rooms?).collect(&:rooms).flatten
end
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
「名前」はわかりやすくシンプル
に
def rooms
return [] if (self.blocks || []).empty?
self.blocks.select(&:has_rooms?).collect(&:rooms).flatten
end
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
もうめんどいからガード条件も
合体
def rooms
(self.blocks || []).select(&:has_rooms?).collect(&:rooms).flatten
end
※空リスト([])のselectやcollectも[]を返す
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
しかも・・・
blocks.select(&:has_rooms?).collect(&:rooms).flatten
「blocksからroomsを持ったものを
選び、roomsを集めてリストにして返
す」と読める
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
"いや、私には関係ないし"
関数型とか使う機会ないですし
Rubyなんてあいまいな言語で書き
ませんし
Javaの方がしっかりしてますし
サーバサイド書きませんし
ScalaでWebとかありえませんし
「もうなにもこわくない」関数型言語 by @parrot_studio for Gunma.web #13 on 2013/05/18
すぐにできること
メソッドを簡潔にまとめる
メソッド内のネストを深くしすぎない
深くなる場合はたいてい大きすぎる
「言葉」を重視する
結局、その処理は「何をしたい」のか?