[ruby-list:46526] Re: obj.? メソッド

From: Yusuke ENDOH <mame@...>
Date: 2009-11-05 16:56:07 UTC
List: ruby-list #46526
遠藤です。

2009年11月4日17:00 KISHIMOTO, Makoto <ksmakoto@dd.iij4u.or.jp>:
> レシーバを省略しない呼び出しであれば、現在、obj.def とか obj.end とか obj.and
> とか、演算子やそのほかの構文と被ってる名前でも使えるわけですよね?
> そういうわけで、obj.? もあっていいんではないか、と改めて提案します。

とくに賛成でも反対でもないのですが


> 誰がうれしいか、ということについてですが、パーサコンビネータで、
> a a? b という構文規則をたとえば a >> a.opt >> b としていたものを、
> a >> a.? >> b と、簡潔かつ直感的にわかりやすく書けるようになります。

DSL で欲しい場合がありそうという需要はなんとなく理解はできました。


もし採用するとしても、こういう文法拡張は 2.0 になるかなと思いつつも、
パッチを書いてみました。既存の文法と衝突するところってありますかね。


  $ ./ruby -e '
  class C
    def ?
      :foo
    end
  end

  p C.new.?  #=> :foo
  '
  :foo


diff --git a/parse.y b/parse.y
index c10dfe6..5490367 100644
--- a/parse.y
+++ b/parse.y
@@ -1793,6 +1793,7 @@ op		: '|'		{ ifndef_ripper($$ = '|'); }
 		| '%'		{ ifndef_ripper($$ = '%'); }
 		| tPOW		{ ifndef_ripper($$ = tPOW); }
 		| '!'		{ ifndef_ripper($$ = '!'); }
+		| '?'		{ ifndef_ripper($$ = '?'); }
 		| '~'		{ ifndef_ripper($$ = '~'); }
 		| tUPLUS	{ ifndef_ripper($$ = tUPLUS); }
 		| tUMINUS	{ ifndef_ripper($$ = tUMINUS); }
@@ -6675,6 +6676,10 @@ parser_yylex(struct parser_params *parser)
 	return tSTRING_BEG;

       case '?':
+	if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
+	    lex_state = EXPR_ARG;
+	    return '?';
+	}
 	if (lex_state == EXPR_END || lex_state == EXPR_ENDARG) {
 	    lex_state = EXPR_VALUE;
 	    return '?';

-- 
Yusuke ENDOH <mame@tsg.ne.jp>

In This Thread

Prev Next