[#25636] [Oniguruma 3.X] reggnu.c — "K.Kosako" <sndgk393@...>

さっき気がついたのですが、元々は

15 messages 2005/02/05

[#25655] openssl binding for SSL_CTX_set_default_verify_paths and X509_STORE_set_default_paths — Tanaka Akira <akr@...17n.org>

open-uri で https を扱うことを考えていろいろと調べていた所、openssl で、

9 messages 2005/02/08
[#25670] Re: openssl binding for SSL_CTX_set_default_verify_paths and X509_STORE_set_default_paths — GOTOU Yuuzou <gotoyuzo@...> 2005/02/10

In message <876513vce0.fsf@serein.a02.aist.go.jp>,

[#25713] pthread trouble on sighandler — Hidetoshi NAGAI <nagai@...>

永井@知能.九工大です.

17 messages 2005/02/18
[#25714] Re: pthread trouble on sighandler — Yukihiro Matsumoto <matz@...> 2005/02/18

まつもと ゆきひろです

[#25755] I/O operation differs signal handler — Minero Aoki <aamine@...>

青木です。

14 messages 2005/02/24
[#25756] Re: I/O operation differs signal handler — Tanaka Akira <akr@...17n.org> 2005/02/24

In article <20050224091450P.aamine@loveruby.net>,

[ruby-dev:25772] behavior

From: nobu@...
Date: 2005-02-26 12:05:30 UTC
List: ruby-dev #25772
なかだです。

[ruby-dev:24302]の野分さんの案について考えていたんですが、Proc
とは別でいいんじゃないかと思えてきました。

元の関数呼出しの話とは離れますが、かわりにこういうものを思い付
きました。

  format = "unknown".behaving(:%) {|s| s ? "#{s}" : self}
  p format % "hoge"
  p format % nil
  hoge = Object.new.behaving(to_s: proc{"hoge"}, to_i: proc{42})
  printf "%s:%d\n", hoge, hoge

rubyでの実装はこんな感じです。

  class Behavior < Module
    def initialize(behavior, &body)
      if body
        define_method(behavior, &body)
      else
        behavior.each do |behavior, body|
          if body
            define_method(behavior, &body)
          elsif body.nil?
            remove_method(behavior)
          else
            undef_method(behavior)
          end
        end
      end
    end
  end

  module Kernel
    def behaving(behavior, &body)
      extend(Behavior.new(behavior, &body))
    end
  end


Cで実装するならこういう感じ。

* eval.c (behavior_initialize): new class Behavior.

* eval.c (rb_behaving): make the receiver to behave as the given proc.


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.755
diff -U2 -p -r1.755 eval.c
--- eval.c	22 Feb 2005 14:57:43 -0000	1.755
+++ eval.c	26 Feb 2005 12:02:17 -0000
@@ -9407,4 +9407,78 @@ rb_mod_define_method(argc, argv, mod)
 }
 
+VALUE rb_cBehavior;
+
+static VALUE
+define_behavior(beh, mod)
+    VALUE beh, mod;
+{
+    VALUE args = rb_check_array_type(beh);
+    VALUE body = Qnil;
+    ID name;
+
+    if (!NIL_P(args)) {
+	name = rb_to_id(rb_ary_entry(args, 0));
+	body = rb_ary_entry(args, 1);
+    }
+    else {
+	name = rb_to_id(args);
+    }
+    if (!body) {
+	rb_add_method(mod, name, 0, NOEX_UNDEF);
+    }
+    else if (NIL_P(body)) {
+	remove_method(mod, name);
+    }
+    else {
+	VALUE arg[2];
+	arg[0] = ID2SYM(name);
+	arg[1] = body;
+	rb_mod_define_method(2, arg, mod);
+	rb_export_method(mod, name, NOEX_PUBLIC);
+    }
+    return Qnil;
+}
+
+/*
+ *  call-seq:
+ *     Behavior.new(symbol) { block }        => behavior
+ *     Behavior.new(name: proc { block })    => behavior
+ *
+ *  Define singleton methods to the given instance.
+ */
+
+static VALUE
+behavior_initialize(self, behavior)
+    VALUE self, behavior;
+{
+    if (rb_block_given_p()) {
+	VALUE arg[2];
+	arg[0] = behavior;
+	arg[1] = proc_lambda();
+	rb_mod_define_method(2, arg, self);
+	rb_export_method(self, rb_to_id(behavior), NOEX_PUBLIC);
+    }
+    else {
+	rb_iterate(rb_each, behavior, define_behavior, self);
+    }
+    return self;
+}
+
+/*
+ *  call-seq:
+ *     obj.behaving(symbol) { block }        => obj
+ *     obj.behaving(name: proc { block })    => obj
+ *
+ *  Defines the given block as the singleton method of the +obj+.
+ */
+
+static VALUE
+rb_behaving(self, behavior)
+    VALUE self, behavior;
+{
+    behavior = behavior_initialize(rb_obj_alloc(rb_cBehavior), behavior);
+    return rb_obj_extend(1, &behavior, self);
+}
+
 /*
  *  <code>Proc</code> objects are blocks of code that have been bound to
@@ -9489,4 +9563,8 @@ Init_Proc()
     rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
     rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
+
+    rb_cBehavior = rb_define_class("Behavior", rb_cModule);
+    rb_define_method(rb_cBehavior, "initialize", behavior_initialize, 1);
+    rb_define_method(rb_mKernel, "behaving", rb_behaving, 1);
 }
 


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

In This Thread

Prev Next