[#29469] エラーを捕まえたいのですが ... — Sakae Kobayashi <sakae@...>

困った時に出てくる、小林榮です。

12 messages 2001/05/01

[#29490] Re: [ruby-talk:14555] Ruby as a Mac OS/X scripting language — maili31s@... (SugHimsi == SUGIHARA Hiroshi)

すぎむし速報。↓だそうです。

12 messages 2001/05/02

[#29524] tr range? — kiri@...

桐山です。

17 messages 2001/05/06
[#29526] Re: tr range? — Koji Arai <JCA02266@...> 2001/05/06

新井です。

[#29644] rwiki.rb でエラー — norio goto <goto@...>

お世話になります、後藤@横河工事です。

18 messages 2001/05/14
[#29645] Re: rwiki.rb でエラー — m_seki@... 2001/05/14

[#29646] Re: rwiki.rb でエラー — norio goto <goto@...> 2001/05/14

後藤@横河工事です。

[#29675] with(obj){ } が欲しい。 — Take_tk <ggb03124@...>

例によって、ワタシ好みののりクエストですみません。

24 messages 2001/05/15
[#29694] Re: with(obj){ } が欲しい。 — "K.Kosako" <kosako@...> 2001/05/17

Take_tkさんの<20010515205133.DFBA.GGB03124@nifty.ne.jp>から

[#29707] OBJECT DAY2001 — "K.Kosako" <kosako@...>

OBJECT DAY2001から帰ってきました。

71 messages 2001/05/18
[#29712] Re: OBJECT DAY2001 — matz@... (Yukihiro Matsumoto) 2001/05/18

まつもと ゆきひろです

[#29719] Re: OBJECT DAY2001 — WATANABE Tetsuya <tetsu@...> 2001/05/21

渡辺哲也です。

[#29731] YARPC 19101 (Re: OBJECT DAY2001) — TAKAHASHI Masayoshi <maki@...> 2001/05/21

YARPC関連で動いてお騒がせしている(_o_)高橋征義です。

[#29792] Re: YARPC 19101 — akira yamada / やまだあきら <akira@...> 2001/05/27

[#29794] Re: YARPC 19101 — Minero Aoki <aamine@...> 2001/05/27

あおきです。

[#29803] Re: YARPC 19101 — Hiroshi IGARASHI <iga@...> 2001/05/27

いがらしです。

[#29721] Cygwin で Ruby をコンパイルするとエラーがでます。 — "Inoue" <inoue@...>

はじめまして、最近Rubyをはじめました井上と申します。

10 messages 2001/05/21

[#29788] marshaled time format differ — IWATSUKI Hiroyuki <don@...>

岩月と申します。

19 messages 2001/05/25
[#29789] Re: marshaled time format differ — matz@... (Yukihiro Matsumoto) 2001/05/25

まつもと ゆきひろです

[#29790] Re: marshaled time format differ — IWATSUKI Hiroyuki <don@...> 2001/05/26

岩月と申します。

[#29823] Re: marshaled time format differ — IWATSUKI Hiroyuki <don@...> 2001/05/27

岩月と申します。

[#29853] "" で行われる展開を eval 無しで… — ABE Shigeru <shiger-a@...>

 みなさま、はじめまして。阿部といいます。

17 messages 2001/05/28
[#29854] Re: "" で行われる展開を eval 無しで… — rubikitch <rubikitch@...> 2001/05/28

From: ABE Shigeru <shiger-a@nifty.com>

[#29941] Ruby ライセンスについて — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

38 messages 2001/05/31
[#29942] Re: Ruby ライセンスについて — Takahiro Kambe <taca@...> 2001/05/31

In message <991297854.779223.23013.nullmailer@ev.netlab.zetabits.com>

[#29944] Re: Ruby ライセンスについて — "Akinori MUSHA" <knu@...> 2001/05/31

At Thu, 31 May 2001 18:00:18 +0900,

[ruby-list:29624] Enumerator

From: "Akinori MUSHA" <knu@...>
Date: 2001-05-10 06:49:21 UTC
List: ruby-list #29624
At Wed, 9 May 2001 17:58:34 +0900,
matz wrote:
> | 少し前に登場した、岡田さん作の EachDelegator:
> |
> |	http://www.ruby-lang.org/en/raa-list.rhtml?name=EachDelegator
> |
> |ですが、これをどうやって標準仕様に取り入れようかという話です。
> 
> 標準って組み込み? ちょっとトリッキーでは?
> 「だめ」とまでは言いませんが。

 その後、ちょっと頭をひねり、メソッドの再定義はやはり邪悪な
感じが拭えないと思い直し、トリック抜きの新しいものを考えました。

 既存のものや今後登場するクラス・モジュールに一切変更を強いず、
また each/each_*/*_each 等のメソッドの再定義も行わない方法です。

============================================================
Enumerable クラス

- インスタンス・メソッド

  enum_with(method, *args)

    each の代わりに method というメソッドを使ってイテレートする
    ための Enumerator オブジェクトを返します。args を指定すると、
    イテレータの呼び出し時の引数として渡されます。

    使用例)

      "foobar".enum_with(:each_byte).collect {|x| "%02x" % x}
      #=> ["66", "6f", "6f", "62", "61", "72"]
============================================================

 名称の enum_with は、「普通は each で enumerate するが、ここは
each_byte で」というニュアンスです。ほかにも、単に「with」という
案も出ており、ぶつからないようならこちらの方が短くていいかも。

============================================================
Enumerator クラス

  Enumerator は、 Enumerable#enum_with の返り値としても得られる。
  each メソッドを提供し、 Enumerable なオブジェクトとして利用
  される。

- インクルードしているモジュール

  Enumerable

- クラス・メソッド

  Enumerator::new(obj, method, *arg)

    オブジェクトの生成。obj オブジェクトの method メソッドに
    args で列挙された引数を与えてイテレートする Enumerable な
    オブジェクトを生成する。

    使用例)

      Enumerator.new(ObjectSpace, :each_object, Class).sort {
        |a,b| a.name <=> b.name
      }
      #=> ["ArgumentError", "Array", "Bignum", ...,
           "UnboundMethod", "ZeroDivisionError", "fatal"]

- インスタンス・メソッド
     
  each

    渡されたブロックを与えてイテレートする。

============================================================


 実装は、 Ruby で書くと次のようなとてもシンプルなものです。

class Enumerator
  include Enumerable
  
  def initialize(enumobj, method, *args)
    @enumobj = enumobj
    @method = method
    @args = args
  end
  
  def each(&block)
    @enumobj.send(@method, *@args, &block)
  end
end

module Enumerable
  def enum_with(method, *args)
    Enumerator.new(self, method, *args)
  end
end

 C による実装は末尾に添付します。


 これがあると何がうれしいかというと、例えば従来:

	ary = []
	"hogehoge".each_byte {|b| ary << b}

と書かざるを得ないときなどは違和感を感じていましたが、これが:

	ary = "hogehoge".enum_with(:each_byte).to_a

と素直に1ステップでできるようになります。(文字数は増えてますが)

 もちろん、 to_a の代わりに collect, select, each_with_index
などの Enumerable モジュールのメソッドが自由に使えます。

 Enumerator の方は、上の例にもある通り、 ObjectSpace::each_object
など、 Enumerable でないものを Enumerable として扱うことを可能に
してくれます。

      Enumerator.new(ObjectSpace, :each_object, Class).sort {
        |a, b| a.name <=> b.name
      }

 どうでしょうか?


P.S.
 fatal はクラスなのに小文字で始まるんですね。

-- 
                     /
                    /__  __            Akinori.org / MUSHA.org
                   / )  )  ) )  /     FreeBSD.org / Ruby-lang.org
Akinori MUSHA aka / (_ /  ( (__(  @ iDaemons.org / and.or.jp

"Freeze this moment a little bit longer, make each impression
  a little bit stronger..  Experience slips away -- Time stand still"

Index: enum.c
===================================================================
RCS file: /src/ruby/enum.c,v
retrieving revision 1.14
diff -u -r1.14 enum.c
--- enum.c	2001/03/13 05:45:08	1.14
+++ enum.c	2001/05/10 06:03:59
@@ -13,8 +13,8 @@
 #include "ruby.h"
 #include "node.h"
 
-VALUE rb_mEnumerable;
-static ID id_each, id_eqq, id_cmp;
+VALUE rb_mEnumerable, rb_cEnumerator;
+static ID id_each, id_eqq, id_cmp, id_enumobj, id_method, id_args, id_new;
 
 VALUE
 rb_each(obj)
@@ -388,6 +388,48 @@
     return Qnil;
 }
 
+static VALUE
+enum_enum_with(obj, args)
+    VALUE obj, args;
+{
+    rb_ary_unshift(args, obj);
+
+    return rb_apply(rb_cEnumerator, id_new, args);
+}
+
+static VALUE
+enumerator_initialize(argc, argv, obj)
+    int argc;
+    VALUE *argv;
+    VALUE obj;
+{
+    VALUE enumobj, method, args;
+
+    rb_scan_args(argc, argv, "2*", &enumobj, &method, &args);
+
+    rb_ivar_set(obj, id_enumobj, enumobj);
+    rb_ivar_set(obj, id_method, rb_String(method));
+    rb_ivar_set(obj, id_args, args);
+
+    return Qnil;
+}
+
+static VALUE
+enumerator_iter(obj)
+    VALUE obj;
+{
+    return rb_apply(rb_ivar_get(obj, id_enumobj),
+		    rb_to_id(rb_ivar_get(obj, id_method)),
+		    rb_ivar_get(obj, id_args));
+}
+
+static VALUE
+enumerator_each(obj)
+    VALUE obj;
+{
+    return rb_iterate(enumerator_iter, obj, rb_yield, 0);
+}
+
 void
 Init_Enumerable()
 {
@@ -413,8 +455,20 @@
     rb_define_method(rb_mEnumerable,"member?", enum_member, 1);
     rb_define_method(rb_mEnumerable,"include?", enum_member, 1);
     rb_define_method(rb_mEnumerable,"each_with_index", enum_each_with_index, 0);
+    rb_define_method(rb_mEnumerable,"enum_with", enum_enum_with, -2);
 
     id_eqq  = rb_intern("===");
     id_each = rb_intern("each");
     id_cmp  = rb_intern("<=>");
+
+    rb_cEnumerator = rb_define_class("Enumerator", rb_cObject);
+    rb_include_module(rb_cEnumerator, rb_mEnumerable);
+
+    rb_define_method(rb_cEnumerator, "initialize", enumerator_initialize, -1);
+    rb_define_method(rb_cEnumerator, "each", enumerator_each, 0);
+
+    id_enumobj  = rb_intern("enumobj");
+    id_method   = rb_intern("method");
+    id_args     = rb_intern("args");
+    id_new      = rb_intern("new");
 }
Index: ruby.h
===================================================================
RCS file: /src/ruby/ruby.h,v
retrieving revision 1.45
diff -u -r1.45 ruby.h
--- ruby.h	2001/05/02 04:22:11	1.45
+++ ruby.h	2001/05/10 06:03:59
@@ -519,6 +519,7 @@
 EXTERN VALUE rb_cClass;
 EXTERN VALUE rb_cDir;
 EXTERN VALUE rb_cData;
+EXTERN VALUE rb_cEnumerator;
 EXTERN VALUE rb_cFalseClass;
 EXTERN VALUE rb_cFile;
 EXTERN VALUE rb_cFixnum;

In This Thread