[#39606] [Feature:trunk] Dir instance methods for relative path — Nobuyoshi Nakada <nobu@...>

なかだです。

15 messages 2009/11/02
[#39607] Re: [Feature:trunk] Dir instance methods for relative path — Yukihiro Matsumoto <matz@...> 2009/11/02

まつもと ゆきひろです

[#39611] Re: [Feature:trunk] Dir instance methods for relative path — KOSAKI Motohiro <kosaki.motohiro@...> 2009/11/02

kosakiです

[#39660] [Bug:trunk] Enumerator.new {|y| y << 1 << 2 << 3 } — Yusuke ENDOH <mame@...>

遠藤です。

14 messages 2009/11/11
[#39661] Re: [Bug:trunk] Enumerator.new {|y| y << 1 << 2 << 3 } — Tanaka Akira <akr@...> 2009/11/11

In article <e0b1e5700911110537u2aacf835pc0aea13d89a92cef@mail.gmail.com>,

[#39685] [Feature #2366] private constant — Yusuke Endoh <redmine@...>

Feature #2366: private constant

23 messages 2009/11/14
[#39689] [Feature #2366] private constant — Yusuke Endoh <redmine@...> 2009/11/14

チケット #2366 が更新されました。 (by Yusuke Endoh)

[#40207] Re: [Feature #2366] private constant — Yusuke ENDOH <mame@...> 2010/01/28

遠藤です。

[#40239] Re: [Feature #2366] private constant — Masatoshi SEKI <m_seki@...> 2010/01/29

咳といいます。

[#40243] Re: [Feature #2366] private constant — Yusuke ENDOH <mame@...> 2010/01/29

遠藤です。

[#40246] Re: [Feature #2366] private constant — Masatoshi SEKI <m_seki@...> 2010/01/29

咳といいます。

[#40247] Re: [Feature #2366] private constant — "NARUSE, Yui" <naruse@...> 2010/01/29

成瀬です。

[#39720] hidden objectって? — keiju@... (Keiju ISHITSUKA)

けいじゅ@いしつかです.

15 messages 2009/11/18
[#39721] Re: hidden objectって? — Yukihiro Matsumoto <matz@...> 2009/11/18

まつもと ゆきひろです

[#39726] Re: hidden objectって? — keiju@... (石塚圭樹) 2009/11/19

けいじゅ@いしつかです.

[#39727] Re: hidden objectって? — Yukihiro Matsumoto <matz@...> 2009/11/19

まつもと ゆきひろです

[#39730] Re: hidden objectって? — keiju@... (石塚圭樹) 2009/11/19

けいじゅ@いしつかです.

[#39735] [Bug:trunk] r25230 causes SEGV arround Marshal — "NARUSE, Yui" <naruse@...> 2009/11/19

以下のコミット以降、後述の現象が発生するそうです。

[#39755] RbConfig.rubybin — Tanaka Akira <akr@...>

ruby コマンドのパス名を返す RbConfig.rubybin というメソッド

18 messages 2009/11/23
[#39756] Re: RbConfig.rubybin — Kouhei Sutou <kou@...> 2009/11/23

須藤です。

[#39814] Re: RbConfig.rubybin — Tanaka Akira <akr@...> 2009/11/30

In article <20091123.123808.1122146273169400964.kou@cozmixng.org>,

[#39815] Re: RbConfig.rubybin — KOSAKI Motohiro <kosaki.motohiro@...> 2009/11/30

> In article <20091123.123808.1122146273169400964.kou@cozmixng.org>,

[#39796] バグ? ブロック引数で to_ary が呼ばれる必要のない場面で呼ばれる — keiju@... (Keiju ISHITSUKA)

けいじゅ@いしつかです.

14 messages 2009/11/27
[#39800] Re: バグ? ブロック引数で to_ary が呼ばれる必要のない場面で呼ばれる — Yukihiro Matsumoto <matz@...> 2009/11/27

まつもと ゆきひろです

[#39803] Re: バグ? ブロック引数で to_ary が呼ばれる必要のない場面で呼ばれる — keiju@... (石塚圭樹) 2009/11/27

けいじゅ@いしつかです.

[#39805] Re: バグ? ブロック引数で to_ary が呼ばれる必要のない場面で呼ばれる — Yukihiro Matsumoto <matz@...> 2009/11/28

まつもと ゆきひろです

[#39806] Re: バグ? ブロック引数で to_ary が呼ばれる必要のない場面で呼ばれる — keiju@... (石塚圭樹) 2009/11/28

けいじゅ@いしつかです.

[#39807] Re: バグ? ブロック引数で to_ary が呼ばれる必要のない場面で呼ばれる — Yukihiro Matsumoto <matz@...> 2009/11/28

まつもと ゆきひろです

[ruby-dev:39685] [Feature #2366] private constant

From: Yusuke Endoh <redmine@...>
Date: 2009-11-14 05:30:32 UTC
List: ruby-dev #39685
Feature #2366: private constant
http://redmine.ruby-lang.org/issues/show/2366

起票者: Yusuke Endoh
ステータス: Open, 優先度: Normal
担当者: Yukihiro Matsumoto, カテゴリ: core, Target version: 1.9.x

遠藤です。

今の Ruby には、クラスが公開 API かどうかを伝える手段がドキュメント
しかありません。そのため、ERB::Compiler など、ライブラリの中の公開
でない (と思われる) inner class を外から自由に参照できてしまいます。

これを防ぐためには、匿名クラスを用いて定義すれば大分隠蔽できますが、
記述が相当煩雑になってしまいます。また、そのようにしてしまうと、
「非公開というのは承知の上で敢えて使いたい」という要求に答えにくく
なります。


そこで、定数に public/private の属性を指定できるようにするのはどう
でしょうか。


  module SomeMod
    class PublicInnerCls
    end

    class PrivateInnerCls
    end

    # PrivateInnerCls を private にする
    private_constant :PrivateInnerCls
  end

  # public な定数は従来どおり参照できる
  p SomeMod::PublicInnerCls  #=> SomeMod::PublicInnerCls

  # private な定数を外から参照しようとすると例外
  p SomeMod::PrivateInnerCls  #=> private constant (RuntimeError)

  # 同じスコープからは参照できる (望むなら自分の足を撃てる)
  p SomeMod.module_eval { PrivateInnerCls }  #=> SomeMod::PrivateInnerCls
  p(module SomeMod; PrivateInnerCls; end)    #=> SomeMod::PrivateInnerCls


要するに、メソッドの public/private と同じ感じです。

細かい仕様は詰めていませんが、proof of concept のパッチを付けます。
1 定数ごとに 2 要素の配列を作ってしまうので、ちゃんとした実装は必要
だと思います。

どんなものでしょうか。


ちなみにこの提案のきっかけは [ruby-dev:39677] です。


diff --git a/variable.c b/variable.c
index 779a8e8..db3a81c 100644
--- a/variable.c
+++ b/variable.c
@@ -1525,6 +1525,33 @@ rb_autoload_p(VALUE mod, ID id)
     return load && (file = load->nd_lit) ? file : Qnil;
 }
 
+void
+rb_change_const_visibility(VALUE klass, ID id, VALUE ex)
+{
+    VALUE value, tmp;
+    int mod_retry = 0;
+
+    tmp = klass;
+    while (RTEST(tmp)) {
+	VALUE am = 0;
+	while (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp), (st_data_t)id, &value)) {
+	    if (value == Qundef) {
+		if (am == tmp) break;
+		am = tmp;
+		rb_autoload_load(tmp, id);
+		continue;
+	    }
+	    if (tmp == rb_cObject && klass != rb_cObject) {
+		rb_warn("toplevel constant %s referenced by %s::%s",
+			rb_id2name(id), rb_class2name(klass), rb_id2name(id));
+	    }
+	    RARRAY_PTR(value)[1] = ex;
+	    return;
+	}
+	tmp = RCLASS_SUPER(tmp);
+    }
+}
+
 static VALUE
 rb_const_get_0(VALUE klass, ID id, int exclude, int recurse)
 {
@@ -1546,7 +1573,10 @@ rb_const_get_0(VALUE klass, ID id, int exclude, int recurse)
 		rb_warn("toplevel constant %s referenced by %s::%s",
 			rb_id2name(id), rb_class2name(klass), rb_id2name(id));
 	    }
-	    return value;
+	    if (!RARRAY_PTR(value)[1]) {
+		rb_raise(rb_eRuntimeError, "private constant");
+	    }
+	    return RARRAY_PTR(value)[0];
 	}
 	if (!recurse && klass != rb_cObject) break;
 	tmp = RCLASS_SUPER(tmp);
@@ -1798,11 +1828,13 @@ mod_av_set(VALUE klass, ID id, VALUE val, int isconst)
 void
 rb_const_set(VALUE klass, ID id, VALUE val)
 {
+    VALUE ary;
     if (NIL_P(klass)) {
 	rb_raise(rb_eTypeError, "no class/module to define constant %s",
 		 rb_id2name(id));
     }
-    mod_av_set(klass, id, val, TRUE);
+    ary = rb_ary_new3(2, val, Qtrue);
+    mod_av_set(klass, id, ary, TRUE);
 }
 
 void
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 0660c7d..e3e789e 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1141,7 +1141,7 @@ vm_get_ev_const(rb_thread_t *th, const rb_iseq_t *iseq,
 			    return 1;
 			}
 			else {
-			    return val;
+			    return RARRAY_PTR(val)[0];
 			}
 		    }
 		}
diff --git a/vm_method.c b/vm_method.c
index 557583f..40b125a 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -1038,6 +1038,30 @@ rb_mod_private_method(int argc, VALUE *argv, VALUE obj)
     return obj;
 }
 
+static void
+set_const_visibility(VALUE self, int argc, VALUE *argv, VALUE ex)
+{
+    int i;
+    extern void rb_change_const_visibility(VALUE klass, ID id, VALUE ex);
+    secure_visibility(self);
+    for (i = 0; i < argc; i++) {
+	rb_change_const_visibility(self, rb_to_id(argv[i]), ex);
+    }
+    rb_clear_cache_by_class(self);
+}
+
+static VALUE
+rb_mod_public_constant(int argc, VALUE *argv, VALUE obj)
+{
+    set_const_visibility(obj, argc, argv, Qtrue);
+}
+
+static VALUE
+rb_mod_private_constant(int argc, VALUE *argv, VALUE obj)
+{
+    set_const_visibility(obj, argc, argv, Qfalse);
+}
+
 /*
  *  call-seq:
  *     public
@@ -1250,6 +1274,8 @@ Init_eval_method(void)
     rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
     rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
     rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
+    rb_define_method(rb_cModule, "public_constant", rb_mod_public_constant, -1);
+    rb_define_method(rb_cModule, "private_constant", rb_mod_private_constant, -1);
 
     rb_define_singleton_method(rb_vm_top_self(), "public", top_public, -1);
     rb_define_singleton_method(rb_vm_top_self(), "private", top_private, -1);

-- 
Yusuke Endoh <mame@tsg.ne.jp>


----------------------------------------
http://redmine.ruby-lang.org

In This Thread

Prev Next