[#42735] [Ruby 1.9-Feature#4147][Open] Array#sample で重みを指定したい — Yoji Ojima <redmine@...>

Feature #4147: Array#sample で重みを指定したい

52 messages 2010/12/10
[#42791] [Ruby 1.9-Feature#4147][Assigned] Array#sample で重みを指定したい — Shyouhei Urabe <redmine@...> 2010/12/18

チケット #4147 が更新されました。 (by Shyouhei Urabe)

[#42800] Re: [Ruby 1.9-Feature#4147][Assigned] Array#sample で重みを指定したい — Masaya TARUI <tarui@...> 2010/12/19

> じゃあ反対ないので実装はともかく、この仕様は基本入れる方向で考えましょう。反対の人は意思表示お早めに。

[#42763] [Ruby 1.9-Bug#4159][Open] test_block_variables(TestRipper::ParserEvents) が失敗する — Kouhei Yanagita <redmine@...>

Bug #4159: test_block_variables(TestRipper::ParserEvents) が失敗する

8 messages 2010/12/14

[#42894] [Ruby 1.8-Feature#4207][Open] これから「1.8.8」の話をしよう -- 1.8がこの先生きのこるには — Shyouhei Urabe <redmine@...>

Feature #4207: これから「1.8.8」の話をしよう -- 1.8がこの先生きのこるには

24 messages 2010/12/26
[#42935] Re: [Ruby 1.8-Feature#4207][Open] これから「1.8.8」の話をしよう -- 1.8がこの先生きのこるには — Kenta Murata <muraken@...> 2011/01/04

むらたです。

[#42936] Re: [Ruby 1.8-Feature#4207][Open] これから「1.8.8」の話をしよう -- 1.8がこの先生きのこるには — Kenta Murata <muraken@...> 2011/01/05

むらたです。

[ruby-dev:42787] Re: [Ruby 1.9-Feature#4146][Open] Improvement of Symbol and Proc

From: Nobuyoshi Nakada <nobu@...>
Date: 2010-12-18 04:47:58 UTC
List: ruby-dev #42787
なかだです。

At Sat, 11 Dec 2010 10:31:10 +0900,
SASADA Koichi wrote in [ruby-dev:42750]::
>> 現在Symbol#to_procで %w[12 45 32].map(&:to_i) のようなことはできますが、
>> 引数を付けてメソッドを呼ぶことはできません。Symbolリテラルに引数を付け
>> たらその引数と共にメソッドを呼ぶProcを作る構文というのはどうでしょうか。
>>
>>   %w[12 45 32].map(&:to_i(9)).map(&:*(2)) #=> [22, 82, 58]
>>   %w[abc def ghi].map(&:[1])              #=> ["b", "e", "h"]
> 
>  メソッドだと,やっぱり書くのがめんどいっすかね?

Symbol#callを定義すれば、こうは書けますが

  p %w[12 45 32].map(&:to_i.(9)).map(&:*.(2))
  p %w[abc def ghi].map(&:[].(1))

>  method_missing を使うのはこんな感じでしょうか.

いずれにせよ引数はProcの作成前に決定されて固定されています。
map(&:to_i.(9))とmap{|_|_.to_i.(9)}は等価ではありません。

>  新しい文法を考えるのなら,& に対するメソッド呼び出しを,Proc 生成へ変
> 換するってのはあるかもしれない.
> 
> p %w[12 45 32].map(&.to_i(9)).map(& * 2)
> p %w[abc def ghi].map(&[1])
> #=>
> p %w[12 45 32].map(&lambda{|recv| recv.to_i(9)}).map(&lambda{|recv| recv
> * 2})
> p %w[abc def ghi].map(&lambda{|recv| recv[1]})

単項演算子とかぶる+,-やリテラルとかぶる%,/,[]などはこの構文でも無理です
が、これでもいいかも。


diff --git i/parse.y w/parse.y
index f2a556a..bd615e5 100644
--- i/parse.y
+++ w/parse.y
@@ -401,6 +401,9 @@ static NODE *match_op_gen(struct parser_params*,NODE*,NODE*);
 static ID  *local_tbl_gen(struct parser_params*);
 #define local_tbl() local_tbl_gen(parser)
 
+static NODE *symbol_lambda_gen(struct parser_params *, ID, NODE *);
+#define symbol_lambda(mid, args) symbol_lambda_gen(parser, mid, args)
+
 static void fixup_nodes(NODE **);
 
 extern int rb_dvar_defined(ID);
@@ -2474,6 +2477,27 @@ block_arg	: tAMPER arg_value
 			$$ = $2;
 		    %*/
 		    }
+		| tAMPER '.' {$<num>$ = ruby_sourceline;}
+		  operation2 opt_paren_args
+		    {
+		    /*%%%*/
+			$$ = symbol_lambda($4, $5);
+			nd_set_line($$, $<num>3);
+			$$ = NEW_BLOCK_PASS($$);
+		    /*%
+			$$ = dispatch3(lambda, $4, $5);
+		    %*/
+		    }
+		| tAMPER '.' {$<num>$ = ruby_sourceline;} '[' aref_args ']'
+		    {
+		    /*%%%*/
+			$$ = symbol_lambda(tAREF, $5);
+			nd_set_line($$, $<num>3);
+			$$ = NEW_BLOCK_PASS($$);
+		    /*%
+			$$ = dispatch3(lambda, tAREF, $5);
+		    %*/
+		    }
 		;
 
 opt_block_arg	: ',' block_arg
@@ -8387,6 +8411,19 @@ arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
 }
 
 static NODE *
+symbol_lambda_gen(struct parser_params *parser, ID mid, NODE *args)
+{
+    const struct vtable *vars = dyna_push();
+    ID tid = internal_id();
+    NODE *lambda = NEW_LAMBDA(0);
+    arg_var(tid);
+    lambda->nd_body = NEW_SCOPE(new_args(NEW_ARGS_AUX(tid, 1), 0, 0, 0, 0),
+				NEW_CALL(NEW_DVAR(tid), mid, args));
+    dyna_pop(vars);
+    return lambda;
+}
+
+static NODE *
 splat_array(NODE* node)
 {
     if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
diff --git i/test/ruby/test_symbol.rb w/test/ruby/test_symbol.rb
index 9061f19..443885d 100644
--- i/test/ruby/test_symbol.rb
+++ w/test/ruby/test_symbol.rb
@@ -88,6 +88,10 @@ class TestSymbol < Test::Unit::TestCase
       ary_ids = ary.collect{|x| x.object_id }
       assert_equal ary_ids, ary.collect(&:object_id)
     end
+
+    assert_equal [2, 4, 6], (1..3).map(&.*(2))
+    assert_equal %w(b e h), %w[abc def ghi].map(&.[1])
+    assert_equal [11, 41, 29], %w[12 45 32].map(&.to_i(9))
   end
 
   def test_call


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread

Prev Next