[#35719] Windows-31J <-> UTF-8 roundtrip — Tanaka Akira <akr@...>
以下のように Windows-31J と UTF-8 が roundtrip するかどうか
成瀬です。
In article <48932335.7010209@airemix.jp>,
成瀬です。
In article <48935EBD.3010603@airemix.jp>,
成瀬です。
[#35724] $SAFE=4の場合のReadline::HISTORY.each — Takao Kouji <kouji@...7.net>
knu さんへ
[#35726] "\x01\x00\x00\x00\x00\x00\x00\x21".encode("utf-8", "utf-32be", :invalid=>:replace) — Tanaka Akira <akr@...>
UTF-32BE で、文字として正しくない 4バイトと、文字として正し
[#35733] Re: [ruby-core:18078] We'll release 1.8.6/1.8.7 this Friday, #2 — Urabe Shyouhei <shyouhei@...>
というわけでそろそろリリースしようと思います。予定日は8月8日です。問題点
[#35745] [Bug:1.9] default_external depends on the order of -K and -E — sheepman <sh@...>
こんにちは sheepman です。
成瀬です。
Yuguiです。
[#35763] 文字コードがシンボルでないのは何故? — take_tk <ggb03124@...>
たけ(tk)です。
なかだです。
たけ(tk)です
[#35789] [Ruby 1.9 - Bug #407] (Open) String#<< — Shyouhei Urabe <redmine@...>
チケット #407 が報告されました。 (by Shyouhei Urabe)
まつもと ゆきひろです
Yukihiro Matsumoto さんは書きました:
まつもと ゆきひろです
成瀬です。
At 08:00 08/09/20, NARUSE, Yui wrote:
まつもと ゆきひろです
[#35811] fail to build extension libraries that includes some ruby header files — "Yusuke ENDOH" <mame@...>
遠藤です。
[#35834] 「サポートレベル」の定義、1.9.1のサポート予定プラットフォーム、メンテナ募集 — "Yugui (Yuki Sonoda)" <yugui@...>
Yuguiです。
[#35845] [Bug #437] test_strftime(TestTime) fails on Solaris — Shugo Maeda <redmine@...>
Bug #437: test_strftime(TestTime) fails on Solaris
前田です。
さとうふみやす @ OSS テクノロジです。
まつもと ゆきひろです
前田です。
まつもと ゆきひろです
前田です。
前田です。
まつもと ゆきひろです
前田です。
[#35851] [Feature:1.9] name referencing in sprintf — "Yusuke ENDOH" <mame@...>
遠藤です。
[#35863] Refactoring of enumerating prime numbers — "Yugui (Yuki Sonoda)" <yugui@...>
Yuguiです。
けいじゅ@いしつかです.
Yuguiです。
けいじゅ@いしつかです.
なかだです。
けいじゅ@いしつかです.
なかだです。
けいじゅ@いしつかです.
Yuguiです。
けいじゅ@いしつかです.
[#35899] [Bug #466] test_str_crypt(TestM17NComb) failed — Kazuhiro NISHIYAMA <redmine@...>
Bug #466: test_str_crypt(TestM17NComb) failed
[#35904] [Feature:1.9] pack format 'm' based on RFC 4648 — "Yusuke ENDOH" <mame@...>
遠藤です。
チケット #471 が更新されました。 (by Yuki Sonoda)
遠藤です。
In article <e0b1e5700809220338g5f3b5627p95e94744d5c10505@mail.gmail.com>,
遠藤です。
In article <e0b1e5700809231144n376fd4eencfe06c49ed66665e@mail.gmail.com>,
遠藤です。
[#35906] %N for Time#strftime — "Shugo Maeda" <shugo@...>
前田です。
In article <704d5db90808210811p7f3aef73h97913ade156323f3@mail.gmail.com>,
なかだです。
まつもと ゆきひろです
[#35922] [Bug #475] cgi.rbにNKFに依存したコードが入っている — Takeyuki Fujioka <redmine@...>
Bug #475: cgi.rbにNKFに依存したコードが入っている
[#35945] Re: [ruby-list:45386] Re: [ANN] REXMLのDoS脆弱性 — "Shugo Maeda" <shugo@...>
前田です。
前田です。
In message <704d5db90809010656k2042969bx3d8a4abdafeeea8e@mail.gmail.com>
[#35954] Re: [ruby-cvs:26052] Ruby:r18834 (trunk): * compile.c (defined_expr): should handle NODE_{AND,OR} as — SASADA Koichi <ko1@...>
ささだです.
まつもと ゆきひろです
ささだです.
まつもと ゆきひろです
ささだです.
まつもと ゆきひろです
[#35977] block parameter for Delagator — keiju@... (Keiju ISHITSUKA)
けいじゅ@いしつかです.
[#35986] 1.9と1.8で、delegateのインスタンスのクラス名の違う — Fujioka <fuj@...>
xibbarこと藤岡です。
まつもと ゆきひろです
けいじゅ@いしつかです.
藤岡です。
けいじゅ@いしつかです.
こんにちは、なかむら(う)です。
[#36008] [Bug #505] 1.upto 2 {|i| p i } — Shyouhei Urabe <redmine@...>
Bug #505: 1.upto 2 {|i| p i }
[#36028] [Bug #513] Tempfile yields [BUG] Stack consistency error — Shyouhei Urabe <redmine@...>
Bug #513: Tempfile yields [BUG] Stack consistency error
[#36033] [Bug #515] String#rindexが期待通りに動かない — Takeyuki Fujioka <redmine@...>
Bug #515: String#rindexが期待通りに動かない
[#36048] TypeError from Encoding.compatible? (r18920) — Yukihiro Matsumoto <matz@...>
まつもと ゆきひろです
[#36066] Numeric#scalar? — Tadayoshi Funaba <tadf@...>
1.9 の Numeric#scalar? について、適当でないのでは (real? などのほうがい
原です。
> やはり、scalar? はずれているんじゃないかな。real? の方がいい
原です。
> ここで、scalar? を疑問視する理由を復習すると、たとえば、「複
1.9.1 までに時間がないので scalar? だけ何とかしたいと思っていましたが、
前田です。
原です。
[ruby-dev:35903] Enumerable object from a block
ブロックで簡単に Enumerable なオブジェクトを作れる機能を追加
しようと思いますが、どうでしょうか。
いちいちクラスを作ったり、 extend(Enumerable) して特異メソッド
each を定義したりしなくて済みます。
# フィボナッチ数列(n>=1)
fib = Enumerator.new { |y|
a = b = 1
loop {
y << a
a, b = b, a + b
}
}
p fib.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
元は Ruby 1.8 の generator.rb についていたおまけ機能ですが、
手軽に無限リストや柔軟な繰り返しを定義できるので便利です。
--
Akinori MUSHA / http://akinori.org/
Index: enumerator.c
===================================================================
--- enumerator.c (revision 18754)
+++ enumerator.c (working copy)
@@ -35,6 +35,22 @@ struct enumerator {
VALUE no_next;
};
+static VALUE rb_cGenerator, rb_cYielder;
+
+struct generator {
+ VALUE proc;
+};
+
+struct yielder {
+ VALUE proc;
+};
+
+static VALUE generator_allocate(VALUE klass);
+static VALUE generator_init(VALUE obj, VALUE proc);
+
+/*
+ * Enumerator
+ */
static void
enumerator_mark(void *p)
{
@@ -242,25 +258,53 @@ enumerator_init(VALUE enum_obj, VALUE ob
/*
* call-seq:
* Enumerator.new(obj, method = :each, *args)
+ * Enumerator.new { |y| ... }
*
* Creates a new Enumerator object, which is to be used as an
- * Enumerable object using the given object's given method with the
- * given arguments.
+ * Enumerable object iterating in a given way.
*
- * Use of this method is discouraged. Use Kernel#enum_for() instead.
+ * In the first form, a generated Enumerator iterates over the given
+ * object using the given method with the given arguments passed.
+ * Use of this form is discouraged. Use Kernel#enum_for(), alias
+ * to_enum, instead.
+ *
+ * e = Enumerator.new(ObjectSpace, :each_object)
+ * #-> ObjectSpace.enum_for(:each_object)
+ *
+ * e.select { |obj| obj.is_a?(Class) } #=> array of all classes
+ *
+ * In the second form, iteration is defined by the given block, in
+ * which a "yielder" object given as block parameter can be used to
+ * yield a value by calling the +yield+ method, alias +<<+.
+ *
+ * fib = Enumerator.new { |y|
+ * a = b = 1
+ * loop {
+ * y << a
+ * a, b = b, a + b
+ * }
+ * }
+ *
+ * p fib.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
*/
static VALUE
enumerator_initialize(int argc, VALUE *argv, VALUE obj)
{
VALUE recv, meth = sym_each;
- if (argc == 0)
- rb_raise(rb_eArgError, "wrong number of argument (0 for 1)");
- recv = *argv++;
- if (--argc) {
- meth = *argv++;
- --argc;
+ if (argc == 0) {
+ if (!rb_block_given_p())
+ rb_raise(rb_eArgError, "wrong number of argument (0 for 1+)");
+
+ recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc());
+ } else {
+ recv = *argv++;
+ if (--argc) {
+ meth = *argv++;
+ --argc;
+ }
}
+
return enumerator_init(obj, recv, meth, argc, argv);
}
@@ -471,6 +515,217 @@ enumerator_rewind(VALUE obj)
return obj;
}
+/*
+ * Yielder
+ */
+static void
+yielder_mark(void *p)
+{
+ struct yielder *ptr = p;
+ rb_gc_mark(ptr->proc);
+}
+
+static struct yielder *
+yielder_ptr(VALUE obj)
+{
+ struct yielder *ptr;
+
+ Data_Get_Struct(obj, struct yielder, ptr);
+ if (RDATA(obj)->dmark != yielder_mark) {
+ rb_raise(rb_eTypeError,
+ "wrong argument type %s (expected %s)",
+ rb_obj_classname(obj), rb_class2name(rb_cYielder));
+ }
+ if (!ptr || ptr->proc == Qundef) {
+ rb_raise(rb_eArgError, "uninitialized yielder");
+ }
+ return ptr;
+}
+
+/* :nodoc: */
+static VALUE
+yielder_allocate(VALUE klass)
+{
+ struct yielder *ptr;
+ VALUE obj;
+
+ obj = Data_Make_Struct(klass, struct yielder, yielder_mark, -1, ptr);
+ ptr->proc = Qundef;
+
+ return obj;
+}
+
+static VALUE
+yielder_init(VALUE obj, VALUE proc)
+{
+ struct yielder *ptr;
+
+ Data_Get_Struct(obj, struct yielder, ptr);
+
+ if (!ptr) {
+ rb_raise(rb_eArgError, "unallocated yielder");
+ }
+
+ ptr->proc = proc;
+
+ return obj;
+}
+
+/* :nodoc: */
+static VALUE
+yielder_initialize(VALUE obj)
+{
+ rb_need_block();
+
+ return yielder_init(obj, rb_block_proc());
+}
+
+/* :nodoc: */
+static VALUE
+yielder_yield(VALUE obj, VALUE args)
+{
+ struct yielder *ptr = yielder_ptr(obj);
+
+ rb_proc_call(ptr->proc, args);
+
+ return obj;
+}
+
+static VALUE
+yielder_new_i(VALUE dummy)
+{
+ return yielder_init(yielder_allocate(rb_cYielder), rb_block_proc());
+}
+
+static VALUE
+yielder_yield_i(VALUE obj, VALUE memo, int argc, VALUE *argv)
+{
+ return rb_yield(obj);
+}
+
+static VALUE
+yielder_new(void)
+{
+ return rb_iterate(yielder_new_i, (VALUE)0, yielder_yield_i, (VALUE)0);
+}
+
+/*
+ * Generator
+ */
+static void
+generator_mark(void *p)
+{
+ struct generator *ptr = p;
+ rb_gc_mark(ptr->proc);
+}
+
+static struct generator *
+generator_ptr(VALUE obj)
+{
+ struct generator *ptr;
+
+ Data_Get_Struct(obj, struct generator, ptr);
+ if (RDATA(obj)->dmark != generator_mark) {
+ rb_raise(rb_eTypeError,
+ "wrong argument type %s (expected %s)",
+ rb_obj_classname(obj), rb_class2name(rb_cGenerator));
+ }
+ if (!ptr || ptr->proc == Qundef) {
+ rb_raise(rb_eArgError, "uninitialized generator");
+ }
+ return ptr;
+}
+
+/* :nodoc: */
+static VALUE
+generator_allocate(VALUE klass)
+{
+ struct generator *ptr;
+ VALUE obj;
+
+ obj = Data_Make_Struct(klass, struct generator, generator_mark, -1, ptr);
+ ptr->proc = Qundef;
+
+ return obj;
+}
+
+static VALUE
+generator_init(VALUE obj, VALUE proc)
+{
+ struct generator *ptr;
+
+ Data_Get_Struct(obj, struct generator, ptr);
+
+ if (!ptr) {
+ rb_raise(rb_eArgError, "unallocated generator");
+ }
+
+ ptr->proc = proc;
+
+ return obj;
+}
+
+VALUE rb_obj_is_proc(VALUE proc);
+
+/* :nodoc: */
+static VALUE
+generator_initialize(int argc, VALUE *argv, VALUE obj)
+{
+ VALUE proc;
+
+ if (argc == 0) {
+ rb_need_block();
+
+ proc = rb_block_proc();
+ } else {
+ rb_scan_args(argc, argv, "1", &proc);
+
+ if (!rb_obj_is_proc(proc))
+ rb_raise(rb_eTypeError,
+ "wrong argument type %s (expected Proc)",
+ rb_obj_classname(proc));
+
+ if (rb_block_given_p()) {
+ rb_warn("given block not used");
+ }
+ }
+
+ return generator_init(obj, proc);
+}
+
+/* :nodoc: */
+static VALUE
+generator_init_copy(VALUE obj, VALUE orig)
+{
+ struct generator *ptr0, *ptr1;
+
+ ptr0 = generator_ptr(orig);
+
+ Data_Get_Struct(obj, struct generator, ptr1);
+
+ if (!ptr1) {
+ rb_raise(rb_eArgError, "unallocated generator");
+ }
+
+ ptr1->proc = ptr0->proc;
+
+ return obj;
+}
+
+/* :nodoc: */
+static VALUE
+generator_each(VALUE obj)
+{
+ struct generator *ptr = generator_ptr(obj);
+ VALUE yielder;
+
+ yielder = yielder_new();
+
+ rb_proc_call(ptr->proc, rb_ary_new3(1, yielder));
+
+ return obj;
+}
+
void
Init_Enumerator(void)
{
@@ -497,9 +752,24 @@ Init_Enumerator(void)
rb_define_method(rb_cEnumerator, "next", enumerator_next, 0);
rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
- rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
+ rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
- sym_each = ID2SYM(rb_intern("each"));
+ /* Generator */
+ rb_cGenerator = rb_define_class_under(rb_cEnumerator, "Generator", rb_cObject);
+ rb_include_module(rb_cGenerator, rb_mEnumerable);
+ rb_define_alloc_func(rb_cGenerator, generator_allocate);
+ rb_define_method(rb_cGenerator, "initialize", generator_initialize, -1);
+ rb_define_method(rb_cGenerator, "initialize_copy", generator_init_copy, 1);
+ rb_define_method(rb_cGenerator, "each", generator_each, 0);
+
+ /* Yielder */
+ rb_cYielder = rb_define_class_under(rb_cEnumerator, "Yielder", rb_cObject);
+ rb_define_alloc_func(rb_cYielder, yielder_allocate);
+ rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
+ rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
+ rb_define_method(rb_cYielder, "<<", yielder_yield, -2);
+
+ sym_each = ID2SYM(rb_intern("each"));
rb_provide("enumerator.so"); /* for backward compatibility */
}