%
リテラル宣言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.y
Yaccを使用.
字句解析にはflexなどは使っておらず, 直接書かれていて複雑そうである.
%
が字句解析されるまでyylex
parser_yylex
parse_percent
yylex
例のアレ
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.html
logo_full.svg
logo_pawoo.png
logo.png
ruby.svg