[Ruby 1.9 - Feature #4653][Open] [PATCH 1/1] new method Enumerable#rude_map

Issue #4653 has been reported by Shyouhei U…


Feature #4653: [PATCH 1/1] new method Enumerable#rude_map

Author: Shyouhei U.
Status: Open
Priority: Normal
Assignee: Yukihiro M.
Category: core
Target version: 1.9.3

From e6dd7bd9b5769bae5d81416da7a2b4003a43ba06 Mon Sep 17 00:00:00 2001
Message-Id:
[email protected]
From: URABE, Shyouhei [email protected]
Date: Sun, 8 May 2011 22:51:28 +0900
Subject: [PATCH 1/1] new method Enumerable#rude_map

時としてmapが配列を返さない方がいいのにと思うことがあります。

例としてはlzmaで圧縮されており解凍するととても大きくなるテキストファ
イルがあったとして、それを解凍して行番号をふってからHTML escapeして

ではさんでから連結したものをlzmaで圧縮しなおす必要があっ

たとします(注:実話)。ここで「行番号をふって」と「HTML escapeして」を
素直に考えると、lzcatをpopenしたものに対して
io.each_line.map.with_index.map. … とかいう構造がRubyとしては自然
かと思います。が、mapが配列を作ってしまうというのがメモリ消費量的に
よくありません。できればEnumeratorですっきりと処理したいところです。

というわけでmapなんだけど配列じゃなくてEnumeratorを返すmapの変種があ
るといいとおもうのですがどうでしょうか。1.9にはもうflat_mapがあるの
でなんとか_mapが増える心理的抵抗は少ないかなと思うので新規メソッドに
してみました。いきなりmapの戻り値の型が変わるのでも私はいいですけど
ちょっとやりすぎかとも思います。

Signed-off-by: URABE, Shyouhei [email protected]

diff --git a/enum.c b/enum.c
index 584b838…449406b 100644
— a/enum.c
+++ b/enum.c
@@ -462,6 +462,41 @@ enum_flat_map(VALUE obj)
return ary;
}

+static VALUE
+rude_map_ii(VALUE i, VALUE y, int c, VALUE *v)
+{

  • return rb_funcall(y, rb_intern(“<<”), 1, enum_yield(c, v));
    +}

+static VALUE
+rude_map_i(VALUE y, VALUE i, int c, VALUE *v)
+{

  • return rb_block_call(i, id_each, 0, 0, rude_map_ii, y);
    +}

+/*

    • call-seq:
    • enum.rude_map {| obj | block }  -> enumerator
      
    • enum.rude_map                   -> enumerator
      
    • Identical to Enumerable#map, except that it returns an enumerator
    • rather than an array.
    • Without a block it is just another Object#to_enum.
  • */

+static VALUE
+enum_rude_map(VALUE obj)
+{

  • VALUE ret;
  • RETURN_ENUMERATOR(obj, 0, 0);
  • ret = rb_obj_alloc(rb_cEnumerator);
  • rb_block_call(ret, rb_intern(“initialize”), 0, 0, rude_map_i, obj);
  • return ret;
    +}

/*

  • call-seq:
  • enum.to_a      ->    array
    

@@ -2679,6 +2714,7 @@ Init_Enumerable(void)
rb_define_method(rb_mEnumerable, “collect”, enum_collect, 0);
rb_define_method(rb_mEnumerable, “map”, enum_collect, 0);
rb_define_method(rb_mEnumerable, “flat_map”, enum_flat_map, 0);

  • rb_define_method(rb_mEnumerable, “rude_map”, enum_rude_map, 0);
    rb_define_method(rb_mEnumerable, “collect_concat”, enum_flat_map,
    0);
    rb_define_method(rb_mEnumerable, “inject”, enum_inject, -1);
    rb_define_method(rb_mEnumerable, “reduce”, enum_inject, -1);

    1.7.0.4

Issue #4653 has been updated by Shyouhei U…

Status changed from Open to Assigned


Feature #4653: [PATCH 1/1] new method Enumerable#rude_map

Author: Shyouhei U.
Status: Assigned
Priority: Normal
Assignee: Yukihiro M.
Category: core
Target version: 1.9.3

From e6dd7bd9b5769bae5d81416da7a2b4003a43ba06 Mon Sep 17 00:00:00 2001
Message-Id:
[email protected]
From: URABE, Shyouhei [email protected]
Date: Sun, 8 May 2011 22:51:28 +0900
Subject: [PATCH 1/1] new method Enumerable#rude_map

時としてmapが配列を返さない方がいいのにと思うことがあります。

例としてはlzmaで圧縮されており解凍するととても大きくなるテキストファ
イルがあったとして、それを解凍して行番号をふってからHTML escapeして

ではさんでから連結したものをlzmaで圧縮しなおす必要があっ

たとします(注:実話)。ここで「行番号をふって」と「HTML escapeして」を
素直に考えると、lzcatをpopenしたものに対して
io.each_line.map.with_index.map. … とかいう構造がRubyとしては自然
かと思います。が、mapが配列を作ってしまうというのがメモリ消費量的に
よくありません。できればEnumeratorですっきりと処理したいところです。

というわけでmapなんだけど配列じゃなくてEnumeratorを返すmapの変種があ
るといいとおもうのですがどうでしょうか。1.9にはもうflat_mapがあるの
でなんとか_mapが増える心理的抵抗は少ないかなと思うので新規メソッドに
してみました。いきなりmapの戻り値の型が変わるのでも私はいいですけど
ちょっとやりすぎかとも思います。

Signed-off-by: URABE, Shyouhei [email protected]

diff --git a/enum.c b/enum.c
index 584b838…449406b 100644
— a/enum.c
+++ b/enum.c
@@ -462,6 +462,41 @@ enum_flat_map(VALUE obj)
return ary;
}

+static VALUE
+rude_map_ii(VALUE i, VALUE y, int c, VALUE *v)
+{

  • return rb_funcall(y, rb_intern(“<<”), 1, enum_yield(c, v));
    +}

+static VALUE
+rude_map_i(VALUE y, VALUE i, int c, VALUE *v)
+{

  • return rb_block_call(i, id_each, 0, 0, rude_map_ii, y);
    +}

+/*

    • call-seq:
    • enum.rude_map {| obj | block }  -> enumerator
      
    • enum.rude_map                   -> enumerator
      
    • Identical to Enumerable#map, except that it returns an enumerator
    • rather than an array.
    • Without a block it is just another Object#to_enum.
  • */

+static VALUE
+enum_rude_map(VALUE obj)
+{

  • VALUE ret;
  • RETURN_ENUMERATOR(obj, 0, 0);
  • ret = rb_obj_alloc(rb_cEnumerator);
  • rb_block_call(ret, rb_intern(“initialize”), 0, 0, rude_map_i, obj);
  • return ret;
    +}

/*

  • call-seq:
  • enum.to_a      ->    array
    

@@ -2679,6 +2714,7 @@ Init_Enumerable(void)
rb_define_method(rb_mEnumerable, “collect”, enum_collect, 0);
rb_define_method(rb_mEnumerable, “map”, enum_collect, 0);
rb_define_method(rb_mEnumerable, “flat_map”, enum_flat_map, 0);

  • rb_define_method(rb_mEnumerable, “rude_map”, enum_rude_map, 0);
    rb_define_method(rb_mEnumerable, “collect_concat”, enum_flat_map,
    0);
    rb_define_method(rb_mEnumerable, “inject”, enum_inject, -1);
    rb_define_method(rb_mEnumerable, “reduce”, enum_inject, -1);

    1.7.0.4

$B1sF#$G$9!#(B

2011$BG/(B5$B7n(B8$BF|(B23:01 Shyouhei U. [email protected]:

$B$H$$$&$o$1$G(Bmap$B$J$s$@$1$IG[Ns$8$c$J$/$F(BEnumerator$B$rJV$9(Bmap$B$NJQ<o$,$"(B

$B$k$H$$$$$H$*$b$&$N$G$9$,$I$&$G$7$g$&$+!#(B

$B;?@.$G$9!#0J2<$N$h$&$J%3!<%I$r=q$/$H$-$$$D$b5$$K$J$C$F$^$7$?!#(B

big_ary.map {|x| … }.max

$B$?$@!“(Bmap $B$@$1$G$J$/!”(Bselect $B$d(B take $B$K$bE,MQ$G$-$k(B
convension
$B$r7h$a$k$Y$-$@$H;W$$$^$9!#(B

$B!VCY1dI>2A!W$N1Q8l$O!“IaDL$O(B lazy $B$+(B delay $B$@$H;W$$$^$9!#(B
rude $B$H$$$&$N$rJ9$$$?$3$H$,$”$j$^$;$s!#$?$@$$$:$l$K$7$F$b(B 5 $BJ8;z(B
$B0J>e$NDI2C$OD9$9$.$k$h$&$K;W$$$^$9!#(B

$B1sF#$O$+$D$F(B -er (-or) $B$N@\Hx<-$rDs0F$7$^$7$?(B ($B$D$^$j(B
mapper) $B!#(B
http://d.hatena.ne.jp/ku-ma-me/20091111/p2

$B0J2<$NJ}$O(B _lz $B$N@\Hx<-$rDs0F$5$l$F$$$^$9!#(B

$B$$$-$J$j(Bmap$B$NLa$jCM$N7?$,JQ$o$k$N$G$b;d$O$$$$$G$9$1$I(B
$B$A$g$C$H$d$j$9$.$+$H$b;W$$$^$9!#(B

2.0 $B$G$J$i!"$3$l$b$$$$$H;W$$$^$9!#(B

(05/08/2011 11:21 PM), Yusuke ENDOH wrote:

$B1sF#$G$9!#(B

2011$BG/(B5$B7n(B8$BF|(B23:01 Shyouhei U. [email protected]:

$B$H$$$&$o$1$G(Bmap$B$J$s$@$1$IG[Ns$8$c$J$/$F(BEnumerator$B$rJV$9(Bmap$B$NJQ<o$,$"(B

$B$k$H$$$$$H$*$b$&$N$G$9$,$I$&$G$7$g$&$+!#(B

$B;?@.$G$9!#0J2<$N$h$&$J%3!<%I$r=q$/$H$-$$$D$b5$$K$J$C$F$^$7$?!#(B

big_ary.map {|x| … }.max

$B$?$V$s(B def map; Enumerator.new {|y| each {|i| y << yield(i) } };
end
$B$O$
$s$J0l2s$O=q$$$?$3$H$,$“$k$H;W$&$N$G!”<{MW$O$[$\LdBj$J$$$+$H;W$$$^$9(B

$B$?$@!“(Bmap $B$@$1$G$J$/!”(Bselect $B$d(B take $B$K$bE,MQ$G$-$k(B convension
$B$r7h$a$k$Y$-$@$H;W$$$^$9!#(B

$B$^$“!”$=$&$J$l$P$$$$$N$O4V0c$$$J$$$G$9$1$I$b!"OC$rBg$-$/$7$9$.$k$N$bH/;6$7$F=*(B
$BN;$9$k$$$D$b$N%Q%?!<%s$K$J$j$=$&$J5$$b$9$k$N$G!#7x<B$K96$a$?$$$H;W$$$^$9!#(B

$B!VCY1dI>2A!W$N1Q8l$O!“IaDL$O(B lazy $B$+(B delay $B$@$H;W$$$^$9!#(B
rude $B$H$$$&$N$rJ9$$$?$3$H$,$”$j$^$;$s!#$?$@$$$:$l$K$7$F$b(B 5 $BJ8;z(B
$B0J>e$NDI2C$OD9$9$.$k$h$&$K;W$$$^$9!#(B

$BCY1dI>2A$G$“$k$H$_$J$;$k$N$O;v<B$H$7$F$bCY1dI>2A$C$F$$$&8@$$J}$r$7$J$-$c$$$1$J(B
$B$$$3$H$O$J$$$G$9$h$M!#FC$K;d$NMQES$N>l9g$OESCf$GG[Ns$r:n$i$J$$$H$$$&$@$1$NOC$G(B
$B$”$C$F!"7k6IA4ItI>2A$9$k$o$1$G$9$7!#(B

$B$“$H$^$”!“$H$j$”$($:L>A0$,$7$C$/$jMh$J$$$H$-$OD9$a$NL>A0$K$7$H$$$F8e$+$iC;$$$d(B
$B$D$r9M$($k$H$$$&$N$ODj@P$+$H!#$Y$D$K$I$&$7$F$b(Brude$B$8$c$J$-$c$$$+$s$H$$$&?.G0$,(B
$B$"$k$o$1$G$O$J$$$G$9!#(B

$B$$$-$J$j(Bmap$B$NLa$jCM$N7?$,JQ$o$k$N$G$b;d$O$$$$$G$9$1$I(B
$B$A$g$C$H$d$j$9$.$+$H$b;W$$$^$9!#(B

2.0 $B$G$J$i!"$3$l$b$$$$$H;W$$$^$9!#(B

mathn$B$_$?$$$K(Brequire$B$9$k$H5sF0$,>e=q$-$5$l$F!“$$$d$G$b$=$l$O>uBV$,%0%m!<%P%k$@(B
$B$+$i$h$/$J$/$F(Bselector
namespace$B$,$J$$$H!”$G$b$=$l$O$d$C$QOC$,Bg$-$/$J$j$9$.$@(B
$B$J$"!#(B

$B$d$C$Q(Bmap$B$,$$$-$J$jJQ$o$k$N$O7x<B$G$O$J$$$N$G!"<BAu$H$7$F$O:#2sDs0F$7$?$b$N$r(B
$B?d$7$F$$$-$?$$(B(+$BL>A0JQ99$H$+(B)$B$G$9$M!#(B

$BKNIt$G$9!#(B

(05/09/2011 12:35 AM), Yusuke ENDOH wrote:

$B$H$+!#(B
$B8_49@-$,LdBj$J$i!"(BEnumerator $B$N(B #[] $B$H$+$r8F$S=P$7$?$i>!<j$K(B Array
$B$K(B
$B2=$1$k!"$H$+!#(B

$B$H$O$$$($H$j$"$($:(B 1.9 $B$N4V$GN?$0=Q$,$[$7$$5$;}$A$b$o$+$k$N$G!"$&!<$s!"(B
-er $B$,%@%a$J$i@\Hx<-(B L $B$O$I$&$G$7$g$&!#(BmapL $B$H$+(B selectL $B$H$+!#(B
2.0 $B$^$G$KEj$2<N$F$?$/$J$kL>A0!"$H$$$&0UL#$G$O(B rude_ $B$b$$$$$N$+$J$"!#(B

$B$5$9$,$K%-%c%a%k%1!<%9$O$J$$$s$8$c$J$$$G$9$+$M$((B($B2?$,$J$$$C$F!“A0Nc$,(B…)$B!#8D(B
$B?ME*$K$O(Bmapper$B$O$=$s$J$K%@%a$8$c$J$$$H$*$b$&$s$G$9$1$I!”$^$"$^$D$b$H$5$s$,%@(B
$B%a$C$F8@$C$F$k0J>e$O$a$,$J$$$G$9$h$M!#(B

$B$G$^$"$d$O$j(Bflat_map$B$,$"$k0J>e$J$s$H$+(B_map$B$,$$$A$P$sDL$j$d$9$$$H;W$&$s$G$9$1$I(B
$B$I$&$G$9$+$M!#(Blazy_map$B$H$+!#(B

むらたです。

On 2011年5月9日月曜日 at 16:35, Urabe S. wrote:

でまあやはりflat_mapがある以上なんとか_mapがいちばん通りやすいと思うんですけど
どうですかね。lazy_mapとか。

lazy_map がいいです。

$B1sF#$G$9!#(B

2011$BG/(B5$B7n(B9$BF|(B0:07 Urabe S. [email protected]:

$BCY1dI>2A$G$"$k$H$_$J$;$k$N$O;v<B$H$7$F$bCY1dI>2A$C$F$$$&8@$$J}$r$7$J$-$c$$$1$J(B

$B$$$3$H$O$J$$$G$9$h$M!#(B

$B@dBP$K$$$1$J$$$3$H$O$J$$$G$9$,!“0lHLE*$J8@MU$,$”$k$J$i$J$k$Y$/9g$o$;$k(B
$B$Y$-$G$7$g$&!#(B

$BFC$K;d$NMQES$N>l9g$OESCf$GG[Ns$r:n$i$J$$$H$$$&$@$1$NOC$G(B
$B$"$C$F!"7k6IA4ItI>2A$9$k$o$1$G$9$7!#(B

$BCf4V%G!<%?@8@.$N>JN,$OCY1dI>2A$N$"$j$,$?$_$N(B 1 $B$D$G$9!#(B
$B!V7k6IA4ItI>2A$9$k!W$+$I$&$+$O4X78$J$$$H;W$$$^$9!#(B

$B$$$-$J$j(Bmap$B$NLa$jCM$N7?$,JQ$o$k$N$G$b;d$O$$$$$G$9$1$I(B
$B$A$g$C$H$d$j$9$.$+$H$b;W$$$^$9!#(B

2.0 $B$G$J$i!"$3$l$b$$$$$H;W$$$^$9!#(B

mathn$B$_$?$$$K(Brequire$B$9$k$H5sF0$,>e=q$-$5$l$F!"$$$d$G$b$=$l$O>uBV$,%0%m!<%P%k$@(B

$B$+$i$h$/$J$/$F(Bselector
namespace$B$,$J$$$H!“$G$b$=$l$O$d$C$QOC$,Bg$-$/$J$j$9$.$@(B
$B$J$”!#(B

2.0 $B$J$i(B selector namespace ($B$H$$$&$+(B refinement)
$B$,F~$C$F$$$k$O$:!“(B
$B$H$+!#(B
$B8_49@-$,LdBj$J$i!”(BEnumerator $B$N(B #[] $B$H$+$r8F$S=P$7$?$i>!<j$K(B
Array $B$K(B
$B2=$1$k!"$H$+!#(B

$B$H$O$$$($H$j$“$($:(B 1.9
$B$N4V$GN?$0=Q$,$[$7$$5$;}$A$b$o$+$k$N$G!”$&!<$s!“(B
-er $B$,%@%a$J$i@\Hx<-(B L $B$O$I$&$G$7$g$&!#(BmapL $B$H$+(B selectL
$B$H$+!#(B
2.0 $B$^$G$KEj$2<N$F$?$/$J$kL>A0!”$H$$$&0UL#$G$O(B rude_
$B$b$$$$$N$+$J$"!#(B

(05/09/2011 05:21 PM), Akinori MUSHA wrote:

At Mon, 9 May 2011 16:35:31 +0900,
Urabe S. wrote:

$B$G$^$"$d$O$j(Bflat_map$B$,$"$k0J>e$J$s$H$+(B_map$B$,$$$A$P$sDL$j$d$9$$$H;W$&$s$G$9$1$I(B

$B$I$&$G$9$+$M!#(Blazy_map$B$H$+!#(B

$B%Y%?O)@~$J$i(B map_enum $B$,$$$$$H;W$$$^$9!#F0:n$rI=$98l$,J#?tJB$s$G(B
$B$$$?$i!"JV$jCM$O:G8e$N8l$+$iH=CG$9$k$b$N$@$H;W$&$+$i$G$9!#(B

rude$B$d(Blazy$B$OF0:n$J$N$+$H$$$&5?Ld(B($B7AMF;l$G$9$+$i$M$((B)$B$r$5$F$*$/$H$9$k$H!"$=$l$J(B
$B$j$K@bF@NO$,$"$k$h$&$K;W$$$^$7$?!#(B

At Mon, 9 May 2011 16:35:31 +0900,
Urabe S. wrote:

$B$G$^$"$d$O$j(Bflat_map$B$,$"$k0J>e$J$s$H$+(B_map$B$,$$$A$P$sDL$j$d$9$$$H;W$&$s$G$9$1$I(B

$B$I$&$G$9$+$M!#(Blazy_map$B$H$+!#(B

$B%Y%?O)@~$J$i(B map_enum $B$,$$$$$H;W$$$^$9!#F0:n$rI=$98l$,J#?tJB$s$G(B
$B$$$?$i!"JV$jCM$O:G8e$N8l$+$iH=CG$9$k$b$N$@$H;W$&$+$i$G$9!#(B

$B1sF#$G$9!#(B

2011$BG/(B5$B7n(B10$BF|(B23:09 Shota F. [email protected]:

$B6&DL$J(Bconvension$B$rMQ0U$9$k$HH/;6$9$k$H=q$+$l$F$$$?$N$K$d$C$F$7$^$$$^$7$?$,!"(B

Enumerator#defer$B$rDj5A$7$F$3$N$h$&$J7A$K$9$k$HNI$$$N$G$O$H;W$$$^$7$?!#(B

$B8+1I$($O$$$$$G$9$,!";DG0$J$,$i6&DL$N(B convension $B$K$O$J$j$^$;$s!#(B

$ ./ruby -e ‘p [1, 2, 3].select {|x| x.even? }’
[2]

$ ./ruby -e ‘p [1, 2, 3].select.defer {|x| x.even? }.to_a’
[false, true, false]

$B$3$NLdBj$O!"(Bmap $B$d$i(B select $B$d$i$,(B Array
$B$rJV$9$3$HA0Ds$G!"FbItE*$K(B
rb_ary_push $B$r8F$s$G$7$^$C$F$$$k$?$a!“Cf4V%G!<%?@8@.$r2sHr$7$h$&$,(B
$B$J$$$H$$$&$3$H$G$9!#$J$N$G(B mapL $B!”(BselectL
$B$H$$$&$h$&$K3F%a%=%C%I$4$H$K(B
$BBP1~$7$F$$$+$6$k$rF@$^$;$s!#(B

Enumerator $B$+$i(B Array $B$rF@$k$N$O(B to_a
$B0lH/$J$N$G!"%G%U%)%k%H$G(B
Array $B$G$O$J$/(B Enumerator $B$rJV$7$F$/$l$l$P2r7h$J$s$G$9$,!#(B
$B8_49@-0J30$O!#!#(B

Issue #4653 has been updated by Shota F…

共通なconvensionを用意すると発散すると書かれていたのにやってしまいましたが、

Enumerator#deferを定義してこのような形にすると良いのではと思いました。

個人的に見栄えはこれが一番しっくりくるなあ、と思います。

[1,2,3].map.defer{|x| x*2 }.each_with_index.map.defer do |x,i|
“#{x}: #{i}”
end.each {|x| puts x }

いかがでしょうか。

パッチ: a.diff · GitHub

Feature #4653: [PATCH 1/1] new method Enumerable#rude_map

Author: Shyouhei U.
Status: Assigned
Priority: Normal
Assignee: Yukihiro M.
Category: core
Target version: 1.9.3

From e6dd7bd9b5769bae5d81416da7a2b4003a43ba06 Mon Sep 17 00:00:00 2001
Message-Id:
[email protected]
From: URABE, Shyouhei [email protected]
Date: Sun, 8 May 2011 22:51:28 +0900
Subject: [PATCH 1/1] new method Enumerable#rude_map

時としてmapが配列を返さない方がいいのにと思うことがあります。

例としてはlzmaで圧縮されており解凍するととても大きくなるテキストファ
イルがあったとして、それを解凍して行番号をふってからHTML escapeして

ではさんでから連結したものをlzmaで圧縮しなおす必要があっ

たとします(注:実話)。ここで「行番号をふって」と「HTML escapeして」を
素直に考えると、lzcatをpopenしたものに対して
io.each_line.map.with_index.map. … とかいう構造がRubyとしては自然
かと思います。が、mapが配列を作ってしまうというのがメモリ消費量的に
よくありません。できればEnumeratorですっきりと処理したいところです。

というわけでmapなんだけど配列じゃなくてEnumeratorを返すmapの変種があ
るといいとおもうのですがどうでしょうか。1.9にはもうflat_mapがあるの
でなんとか_mapが増える心理的抵抗は少ないかなと思うので新規メソッドに
してみました。いきなりmapの戻り値の型が変わるのでも私はいいですけど
ちょっとやりすぎかとも思います。

Signed-off-by: URABE, Shyouhei [email protected]

diff --git a/enum.c b/enum.c
index 584b838…449406b 100644
— a/enum.c
+++ b/enum.c
@@ -462,6 +462,41 @@ enum_flat_map(VALUE obj)
return ary;
}

+static VALUE
+rude_map_ii(VALUE i, VALUE y, int c, VALUE *v)
+{

  • return rb_funcall(y, rb_intern(“<<”), 1, enum_yield(c, v));
    +}

+static VALUE
+rude_map_i(VALUE y, VALUE i, int c, VALUE *v)
+{

  • return rb_block_call(i, id_each, 0, 0, rude_map_ii, y);
    +}

+/*

    • call-seq:
    • enum.rude_map {| obj | block }  -> enumerator
      
    • enum.rude_map                   -> enumerator
      
    • Identical to Enumerable#map, except that it returns an enumerator
    • rather than an array.
    • Without a block it is just another Object#to_enum.
  • */

+static VALUE
+enum_rude_map(VALUE obj)
+{

  • VALUE ret;
  • RETURN_ENUMERATOR(obj, 0, 0);
  • ret = rb_obj_alloc(rb_cEnumerator);
  • rb_block_call(ret, rb_intern(“initialize”), 0, 0, rude_map_i, obj);
  • return ret;
    +}

/*

  • call-seq:
  • enum.to_a      ->    array
    

@@ -2679,6 +2714,7 @@ Init_Enumerable(void)
rb_define_method(rb_mEnumerable, “collect”, enum_collect, 0);
rb_define_method(rb_mEnumerable, “map”, enum_collect, 0);
rb_define_method(rb_mEnumerable, “flat_map”, enum_flat_map, 0);

  • rb_define_method(rb_mEnumerable, “rude_map”, enum_rude_map, 0);
    rb_define_method(rb_mEnumerable, “collect_concat”, enum_flat_map,
    0);
    rb_define_method(rb_mEnumerable, “inject”, enum_inject, -1);
    rb_define_method(rb_mEnumerable, “reduce”, enum_inject, -1);

    1.7.0.4

(05/10/2011 11:09 PM), Shota F. wrote:

$B6&DL$J(Bconvension$B$rMQ0U$9$k$HH/;6$9$k$H=q$+$l$F$$$?$N$K$d$C$F$7$^$$$^$7$?$,!"(B

$B$^$"$=$&$$$&$o$1$G8+;v$KH/;6$7$F$$$k$N$G!#$d$C$Q$j$H$j$"$($:(Bmap$B$@$1$KCmNO$7$?(B
$B$[$&$,$$$$$H;W$&$o$1$G$9!#$H$j$"$($:<BAu$O$b$&:#$N$G$$$$$s$8$c$J$$$G$9$+$M$(!#(B

$BL>A0$K4X$7$F$O:#$N$H$3$m(Blazy_map$B0F$H(Bmap_enum$B0F$,$"$j$^$9$,$I$&$G$7$g$&$+!#8D?M(B
$BE*$K$O(Blazy_enum$B$,9%$-$+$J$H;W$$$^$9$,!#(B

2011/5/11 Yusuke ENDOH [email protected]:

$B$3$NLdBj$O!"(Bmap $B$d$i(B select $B$d$i$,(B Array
$B$rJV$9$3$HA0Ds$G!"FbItE*$K(B
rb_ary_push $B$r8F$s$G$7$^$C$F$$$k$?$a!“Cf4V%G!<%?@8@.$r2sHr$7$h$&$,(B
$B$J$$$H$$$&$3$H$G$9!#$J$N$G(B mapL $B!”(BselectL
$B$H$$$&$h$&$K3F%a%=%C%I$4$H$K(B
$BBP1~$7$F$$$+$6$k$rF@$^$;$s!#(B
$B$?$7$+$K!#<BAu$_$?$i$=$s$J46$8$G$7$?!D(B $B;DG0!#(B

$BJL$N%/%i%9$r:n$C$F!“(Bdefer.map{|x|…}$B$H$+(Bto_lazy.map{|x|…}$B$H$+$+$J$”!#(B

$B$3$&$$$&%$%s%?!<%U%'!<%9$G%9%Q%C$H=PMh$kJ}$,8+1I$($O$$$$$s$@$1$I$J$"!D(B

At Tue, 10 May 2011 13:39:49 +0900,
Urabe S. wrote:

rude$B$d(Blazy$B$OF0:n$J$N$+$H$$$&5?Ld(B($B7AMF;l$G$9$+$i$M$((B)$B$r$5$F$*$/$H$9$k$H!"$=$l$J(B

$B$j$K@bF@NO$,$"$k$h$&$K;W$$$^$7$?!#(B

$B$"$"!"(Brude$B$H$+(Blazy$B$_$?$$$J?7$7$$8l$rF3F~$9$k$N$O$"$^$j%Y%?O)@~(B
$B$H$O;W$C$F$J$/$F!"(B map $B$H(B enum $B$r%Y%?$KJB$Y$k$H$7$F!"(B
flat_map
$B$H$$$&$N$,$9$G$K$"$k$N$G!"(B(matz$B0F$N(B) enum_map $B$h$j$O(B
map_enum
$B$H$7$?J}$,$o$+$j$d$9$$$@$m$&$H$$$&OC$G$7$?!#(B

$BC;$a$K$9$k$J$i!"(B map_e, select_e, … $B$G!"(B to_enum $B$K$b(B to_e
$B$N(B
alias $B$rMQ0U$9$l$P!"(B _e
$B%5%U%#%C%/%9$H$$$&(Bconvention$B$K$h$C$FL@2w(B
$B$+$J$H;W$$$^$9!#(B

SOAP4R$B$NFbIt$K(B to Exception $B$N0UL#$G(B to_e
$B$,$"$k$3$H$,5$$K$O$J$j(B
$B$^$9$,!"$9$G$KI8=`%i%$%V%i%j$+$i$O30$l$F$$$k$7!"FbItMQ%a%=%C%I$N(B
$B$h$&$J$N$G5$$K$7$J$/$F$$$$$N$+$J!#(B

$B1sF#$G$9!#(B

2011$BG/(B5$B7n(B13$BF|(B3:44 Urabe S. [email protected]:

$BL>A0$K4X$7$F$O:#$N$H$3$m(Blazy_map$B0F$H(Bmap_enum$B0F$,$"$j$^$9$,$I$&$G$7$g$&$+!#8D?M(B

$BE*$K$O(Blazy_enum$B$,9%$-$+$J$H;W$$$^$9$,!#(B

lazy_enum $B$O(B lazy_map $B$N(B typo $B$G$9$h$M!)(B
$B$I$&$7$F$b$=$3$+$iA*$Y$H8@$o$l$?$i1sF#$b(B lazy_map $B$K0lI<$G$9!#(B

$B$A$J$_$K!"(B

http://d.hatena.ne.jp/ku-ma-me/20091111/p2#c1258760977

$B$G$O(B matz $B$O(B enum_map $B$rDs0F$7$F$$$^$7$?!#(B
$B$5$i$K$J$+$@$5$s$O(B -ing $B$H$$$&0F$r$"$2$F$$$^$7$?!#(B
$B8D?ME*$K$O(B

mapper >= mapping >> mapL >= map_lz >> lazy_map > enum_map > map_enum

$B$G$9!#(BmapE $B!"(Bmap_e $B$H$+$G$b$$$$$+$b!#(B

Issue #4653 has been updated by Yusuke E…

Status changed from Assigned to Rejected

まつもとさんが #4890 のやり方がいいと言ったので (#708) 、
2/8 は Enumerable::Lazy 記念日。


Yusuke E. [email protected]

Feature #4653: [PATCH 1/1] new method Enumerable#rude_map

Author: Shyouhei U.
Status: Rejected
Priority: Normal
Assignee: Yukihiro M.
Category: core
Target version: 2.0.0

From e6dd7bd9b5769bae5d81416da7a2b4003a43ba06 Mon Sep 17 00:00:00 2001
Message-Id:
[email protected]
From: URABE, Shyouhei [email protected]
Date: Sun, 8 May 2011 22:51:28 +0900
Subject: [PATCH 1/1] new method Enumerable#rude_map

時としてmapが配列を返さない方がいいのにと思うことがあります。

例としてはlzmaで圧縮されており解凍するととても大きくなるテキストファ
イルがあったとして、それを解凍して行番号をふってからHTML escapeして

ではさんでから連結したものをlzmaで圧縮しなおす必要があっ

たとします(注:実話)。ここで「行番号をふって」と「HTML escapeして」を
素直に考えると、lzcatをpopenしたものに対して
io.each_line.map.with_index.map. … とかいう構造がRubyとしては自然
かと思います。が、mapが配列を作ってしまうというのがメモリ消費量的に
よくありません。できればEnumeratorですっきりと処理したいところです。

というわけでmapなんだけど配列じゃなくてEnumeratorを返すmapの変種があ
るといいとおもうのですがどうでしょうか。1.9にはもうflat_mapがあるの
でなんとか_mapが増える心理的抵抗は少ないかなと思うので新規メソッドに
してみました。いきなりmapの戻り値の型が変わるのでも私はいいですけど
ちょっとやりすぎかとも思います。

Signed-off-by: URABE, Shyouhei [email protected]

diff --git a/enum.c b/enum.c
index 584b838…449406b 100644
— a/enum.c
+++ b/enum.c
@@ -462,6 +462,41 @@ enum_flat_map(VALUE obj)
return ary;
}

+static VALUE
+rude_map_ii(VALUE i, VALUE y, int c, VALUE *v)
+{

  • return rb_funcall(y, rb_intern(“<<”), 1, enum_yield(c, v));
    +}

+static VALUE
+rude_map_i(VALUE y, VALUE i, int c, VALUE *v)
+{

  • return rb_block_call(i, id_each, 0, 0, rude_map_ii, y);
    +}

+/*

    • call-seq:
    • enum.rude_map {| obj | block }  -> enumerator
      
    • enum.rude_map                   -> enumerator
      
    • Identical to Enumerable#map, except that it returns an enumerator
    • rather than an array.
    • Without a block it is just another Object#to_enum.
  • */

+static VALUE
+enum_rude_map(VALUE obj)
+{

  • VALUE ret;
  • RETURN_ENUMERATOR(obj, 0, 0);
  • ret = rb_obj_alloc(rb_cEnumerator);
  • rb_block_call(ret, rb_intern(“initialize”), 0, 0, rude_map_i, obj);
  • return ret;
    +}

/*

  • call-seq:
  • enum.to_a      ->    array
    

@@ -2679,6 +2714,7 @@ Init_Enumerable(void)
rb_define_method(rb_mEnumerable, “collect”, enum_collect, 0);
rb_define_method(rb_mEnumerable, “map”, enum_collect, 0);
rb_define_method(rb_mEnumerable, “flat_map”, enum_flat_map, 0);

  • rb_define_method(rb_mEnumerable, “rude_map”, enum_rude_map, 0);
    rb_define_method(rb_mEnumerable, “collect_concat”, enum_flat_map,
    0);
    rb_define_method(rb_mEnumerable, “inject”, enum_inject, -1);
    rb_define_method(rb_mEnumerable, “reduce”, enum_inject, -1);

    1.7.0.4