2

Ruby が物事を解析する方法をどのように予測できますか?

文字列を連結しようとしているときに、Ruby で本当に驚くべき解析エラーに遭遇しました。

> "every".capitalize +"thing"
=> NoMethodError: undefined method `+@' for "thing":String

もちろん、余分なスペースを入れても意図したとおりに機能します。

> "every".capitalize + "thing"
=> "Everything"

を持っていると、このエラーが発生しますanything.any_method +"any string"。Ruby が行うことは、括弧が省略され、メソッドに引数を与えようとしていると想定することです。

"every".capitalize( +"thing" )

文字列に単項演算子を定義していないことに気づき、+@そのエラーをスローします。

私の質問は、Ruby パーサーの動作を予測するためにどの原則を使用する必要があるかということです。このエラーは、多くのグーグル検索の後で初めてわかりました。.capitalizeパラメータを取らないことは注目に値します (C ソース コードであっても)。前のオブジェクトに適用されないメソッドを使用すると、+@エラーではなくエラーがスローされundefined method 'capitalize' for "every":Stringます。したがって、この解析は明らかに高レベルです。私は Matz のparser.yを読むほど知識がありません。他にも同様の驚くべきエラーに遭遇しました。Ruby の解析の優先順位を教えてもらえますか?

4

1 に答える 1

3

Ruby がコードをどのように解析しているかを確認したい場合は、パースツリーをダンプできます。つまり、

ruby -e '"every".capitalize +"thing"' --dump parsetree

# @ NODE_SCOPE (line: 1)
# +- nd_tbl: (empty)
# +- nd_args:
# |   (null node)
# +- nd_body:
#     @ NODE_CALL (line: 1)
#     +- nd_mid: :capitalize
#     +- nd_recv:
#     |   @ NODE_STR (line: 1)
#     |   +- nd_lit: "every"
#     +- nd_args:
#         @ NODE_ARRAY (line: 1)
#         +- nd_alen: 1
#         +- nd_head:
#         |   @ NODE_CALL (line: 1)
#         |   +- nd_mid: :+@
#         |   +- nd_recv:
#         |   |   @ NODE_STR (line: 1)
#         |   |   +- nd_lit: "thing"
#         |   +- nd_args:
#         |       (null node)
#         +- nd_next:
#             (null node)

私も時々explainrubyを使うのが好きです。

于 2013-06-24T22:09:23.580 に答える