福澤テクノロジー

おっさんプログラマーが、主に技術的な話をするブログ。

ALCS(仮): Array Literal of Closures and Strings

Lazy Here-document (仮) をmrubyに実装してみた - 福澤テクノロジー を作ってみたものの、まだ使いにくい。
行頭や行末の空白文字がそのまま残ってしまうのが、文章を主としたスクリプトを書く時にインデントが出来ない原因になっている。
そこで思いついたのが、 %W リテラル類似の機能。
%W だと、 #{...} を展開して文字列化してしまうが、これを Proc オブジェクトにすればいい!
%P として実装しよう。
それだけだと、文章中の空白文字がなくなってしまう。ワードの区切りになってしまうから。
文章書きの人が使った時、「せっかく入れた空白が消された!」と思ってしまいそう。
自由なインデントをしつつ、空白文字も残すにはどんなルールがいいか。

方針:

  • 自由にインデントしたいので、行頭の空白文字は消そう。あえて入れたければエスケープすればいい。
  • 行末に空白文字があっても見えない(エディタにもよるが)。見えないものは無いことにしよう。
  • 改行がどこで行われたかは知る必要がある。行末の空白文字は消すが、改行コードは残す。
  • 改行で一旦ワードが終わるようにしておきたい。

これを %p として実装しよう。

これで、Hayat言語の特殊機能 sayCommand - 福澤テクノロジーで使ったスクリプト記法とほぼ同じく書けるようになった。

白 = 0
青 = 1
赤 = 2
class Person
  def say(a)
    a.each do |x|
      case x
      when Proc
        mySetColor(x.call)
      else
        myPrintStr(x)
      end
    end
  end
end
アインシュタイン = Person.new

アインシュタイン.say %p[人生は#{青}退屈すれば長く#{白}、
           #{赤}充実すれば短い#{白}。]


Lazy Here-document(仮) は、この %P %p リテラルとほぼ同じような機能なので、両者を合わせて新しい呼び方にしてみた。
ALCS(仮): Array Literal of Closures and Strings
うーん、いまいち。



テストコードはこんな感じ。これで現状の仕様がわかると思う。

def concat_m(arr)
  arr.map{|x| x.class == Proc ?  x.call().to_s : x }.join('-')
end

answer = 42
a = %P(aa#{1+1}bb)
b = %P[ aa #{1+2} bb ]
c = %P{aa
  #{1+3}
  bb}
d = %P/ aa
  #{1+4}
  bb
  /
e = %P(#{1+5}#{answer})
f = %P{aa bb}
test1 = (concat_m(a) == 'aa-2-bb' and
         concat_m(b) == 'aa-3-bb' and
         concat_m(c) == 'aa-4-bb' and
         concat_m(d) == 'aa-5-bb' and
         concat_m(e) == '6-42' and
         concat_m(f) == 'aa-bb'
        )

a = %p(aa#{1+1}bb)
b = %p[ aa #{1+2} bb ]
c = %p{aa 
  #{1+3} 
  bb}
d = %p/ aa   
  #{1+4}        
  bb     
  /
e = %p(#{1+5}#{answer})
f = %p{aa bb}
test2 = (concat_m(a) == 'aa-2-bb' and
         concat_m(b) == ' aa -3- bb ' and
         concat_m(c) == "aa\n-4-\n-bb" and
         concat_m(d) == " aa\n-5-\n-bb\n" and
         concat_m(e) == '6-42' and
         concat_m(f) == 'aa bb'
        )

ソースコードは、github上に alcs ブランチとしてコミットしました。
以下のコマンドで取れます。

git clone -b alcs git://github.com/FUKUZAWA-Tadashi/mruby.git


Here document の方は、課題を2つ解決しときました。

  • <<<'EOH' で式展開をしないようにした
  • <<<- で終端文字列がインデント出来るようにした

heredoc ブランチは、alcs ブランチに統合しました。