%リテラル宣言
この作品 (index.html) は
クリエイティブ・コモンズ
表示 - 継承 4.0 国際
ライセンスの下に提供されています.
表示される画像等はそれぞれのライセンスに従います.
2017年7月から
Rubyで書かれたマイクロブログサービス, Mastodon及びその派生であるPawooとPawoo Musicを開発. (発表内容とはあまり関係ない)
pixivは前夜祭の主催のようで, 今回, 刺客として送り込まれる.
「1つのこと*をうまくやる」ことができている
私が開発しているのはアプリケーション
ならばこちらからRubyに近づかなければならない
Rubyはオープンソース
まずはバグトラッカーを見てみる
十分強力な文法を持っているように思えるRubyだが, 拡張の提案は未だ多い
%q{select foo from bar}
では%sql{select foo from bar}は?
%は演算子でもある
%Q%%%%%%
辛そう
parse.yYaccを使用.
字句解析にはflexなどは使っておらず, 直接書かれていて複雑そうである.
%が字句解析されるまでyylexparser_yylexparse_percentyylex例のアレ
parser_yylexの呼び出しparser_yylex実際に字句解析が始まるのはここから
文字列が開始されているならば文字列の解析, そうでなければトークンの最初の文字によって特殊化された別の関数を呼び出す.
parse_percent読んで字のごとく
ここにきてようやく演算子か, %記法の開始かが判定される
%記法であれば, 文字列, ワードリスト等の開始を意味するトークンを返す.
lex_state現在状態がいい感じに定義されているビットフィールド
EXPR_BEG_bit+/-が
(演算子ではなく)
符号として解釈される」lex_strterm文字列の終端を表す変数
…と思わせておいて実は式展開が有効かどうかなどを表すenum string_typeというビットフィールド,
開始文字なども含む.
def %fooなどと定義されたメソッドに文字列を第1引数として渡す
%メソッドは演算子と被るので定義できない
%のすぐあとが大文字
(例: %FOO)
の場合は式展開を行う
%W相当のものは式展開内の空白とリテラル内の空白を区別できないので実装できない
クラスメソッドの場合はFoo.%barという形で使用できる
定義から見れば分かりやすいが, いざ使うとなると見た目が若干悪い
tPERCENT_BEGという字句を追加. %記法におけるメソッド名を表す.
tPERCENT_ENDという字句を追加. 文字列を表す.
string_typeにstr_percentを追加.
指定されていた場合, 文字列の終端でtPERCENT_ENDが返される.
既存の%記法は現在の実装と同様に字句解析し,
これで定義されていない記法であると判別したときにtPERCENT_BEGを返す.
%演算子の定義をパースしている部分で%以降のアルファベットも識別子に含めるように.
tPERCENT_BEGで始まりtPERCENT_ENDで終わる,
percentノードを追加.
メソッド呼び出しとして解析される.
メッセージ送信の構文のあとにtPERCENT_BEGがあった場合のノードを追加.
同様にメソッド呼び出しとして解析される.
module M
def self.%m s
'hello, ' + s
end
end
p M.%m{world}
ruby --dump=parsetree
@ NODE_CALL (line: 7. lineno: 7, column: 2)
+- nd_mid: :%m
+- nd_recv:
| @ NODE_CONST (line: 7. lineno: 7, column: 2)
| +- nd_vid: :M
+- nd_args:
@ NODE_ARRAY (line: 7. lineno: 7, column: 4)
+- nd_alen: 1
+- nd_head:
@ NODE_STR (line: 7. lineno: 7, column: 4)
+- nd_lit: "world"
+- nd_next:
(null node)
ruby
"hello, world"
やったぜ
%単独で定義できない%単独での定義の利用場面が思い浮かばないが…「かわいくない」sprintf形式で返答すると扱いやすいが%を%%にする必要があるなど面倒がある. 式展開内の範囲を配列にして渡すという方法も.
お年頃のRuby
スピードも気になるけど, おしゃれもしっかりやっていきましょう.
index.htmllogo_full.svglogo_pawoo.pnglogo.pngruby.svg