Skip to content

Instantly share code, notes, and snippets.

@kkismd
Last active August 29, 2015 14:23
Show Gist options
  • Save kkismd/ce28dc1b16a774bf287c to your computer and use it in GitHub Desktop.
Save kkismd/ce28dc1b16a774bf287c to your computer and use it in GitHub Desktop.
ScalaのOptionをRubyで説明してみる
#! /bin/env ruby
class Option
end
class Some < Option
include Enumerable
def initialize(a)
@a = a
end
def each
yield @a
end
def get_or_else(b)
@a
end
def or_else(b)
self
end
def map(&block)
self.class.new( yield @a )
end
def flat_map(&block)
yield @a
end
def to_a
[@a]
end
end
class None < Option
include Enumerable
def each
# do nothing
end
def get_or_else(b)
b
end
def or_else(b)
b
end
def map(&block)
self
end
def flat_map(&block)
self
end
def to_a
[]
end
end
class Object
def some
Some.new(self)
end
end
def none
None.new
end
if __FILE__ == $0
# or_else, get_or_elseの例
# 名前欄にはfirst_nameとlast_nameどちらか設定されているほうを表示する
# どちらも設定されていなければ"名無しさん"と表示する
User = Struct.new(:first_name, :last_name) do
def display_name
self.first_name.or_else(self.last_name).get_or_else("名無しさん")
# Rubyだとこっちのほうが簡単
# self.first_name || self.last_name || "名無しさん"
end
end
taro = User.new("Taro".some, "Yamada".some)
jiro = User.new(none, "Yamada".some)
saburo = User.new("Saburo".some, none)
shiro = User.new(none, none)
print "TARO: "; p taro.display_name
print "JIRO: "; p jiro.display_name
print "SABURO: "; p saburo.display_name
print "SHIRO: "; p shiro.display_name
# flat_mapを使った計算の連鎖の例
a = 1.some
b = 2.some
c = 3.some
ans1 = a.flat_map {|i|
b.flat_map {|j|
c.map {|k|
i + j + k
}
}
}
print "ans1 is "
p ans1
p ans1.get_or_else(-1)
# 途中で計算に失敗するとそこで打ち切られる(ぬるぽ安全)
a = 1.some
b = none
c = 3.some
ans2 = a.flat_map {|i|
b.flat_map {|j|
c.map {|k|
i + j + k
}
}
}
print "ans2 is "
p ans2
p ans2.get_or_else(-1)
# Nullを含むカラムの扱い例
Stock = Struct.new(:name, :category)
stocks = [
Stock.new("stock1", "衣類".some),
Stock.new("stock2", "靴".some),
Stock.new("stock3", none),
Stock.new("stock4", "衣類".some),
]
category_names = stocks.flat_map{|stock| stock.category.to_a }.uniq.sort.join(",")
print "categoryの一覧は "
p category_names
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment