関連
メソッドチェーンでプログラムを書くことを考えている。
Bool
や Int
にメソッドを追加して、ひとまず今の形になった。
階乗のプログラム
# crystal test4.cr # 遅延評価 class Delay def initialize(&block : String -> Int32) @func = block @flag = false #@value = nil @value = 0 end def force unless @flag ret = @func.call "" @value = ret.nil? ? raise("@func.call is nil. #{@func}") : ret @flag = true end @value end end # Bool 構造体にメソッドを追加 struct Bool def if(t, e) if_base t, e end def if_base(t, e) return t.responds_to?(:force) ? t.force : t if self e.responds_to?(:force) ? e.force : e end end # puts true.if "then", "else" struct Int # 階乗 def fact self.<=(0).if 1, Delay.new{self.-(1).fact.*(self)} end end # 実行 puts 10.fact # => 3628800
ここまでで分かった事
ブロック引数には型をつけなくてはいけない
現状、結果の型が Int32
に固定されている
マクロはインスタンスメソッド扱いでなく、クラスメソッド扱い
true.macro_if...
じゃなくて Bool.macro_if...
になってしまう
これでは目的に合わない
引数は先行評価される
if
で選ばれない方は評価したくないので、本方式となった
続くかな?