[#39604] [Bug #2323] "Z".."Z".succが空 — Hiro Asari <redmine@...>
Bug #2323: "Z".."Z".succが空
[#39606] [Feature:trunk] Dir instance methods for relative path — Nobuyoshi Nakada <nobu@...>
なかだです。
まつもと ゆきひろです
kosakiです
なかだです。
> なかだです。
まつもと ゆきひろです
[#39642] [Bug #2338] 大きなFixnumを値にもつHash#hashが呼び出しごとに変わる — Yuki Sonoda <redmine@...>
Bug #2338: 大きなFixnumを値にもつHash#hashが呼び出しごとに変わる
[#39660] [Bug:trunk] Enumerator.new {|y| y << 1 << 2 << 3 } — Yusuke ENDOH <mame@...>
遠藤です。
In article <e0b1e5700911110537u2aacf835pc0aea13d89a92cef@mail.gmail.com>,
遠藤です。
At Wed, 11 Nov 2009 23:50:47 +0900,
遠藤です。
[#39669] メンテナ確認プロセス終了。メンテナ募集 — "Yugui (Yuki Sonoda)" <yugui@...>
-----BEGIN PGP SIGNED MESSAGE-----
[#39685] [Feature #2366] private constant — Yusuke Endoh <redmine@...>
Feature #2366: private constant
チケット #2366 が更新されました。 (by Yusuke Endoh)
遠藤です。
咳といいます。
遠藤です。
咳といいます。
成瀬です。
咳といいます。
遠藤です。
咳といいます。
[#39696] [Feature #2372] read_all() with buffering — _ wanabe <redmine@...>
Feature #2372: read_all() with buffering
成瀬です。
チケット #2372 が更新されました。 (by _ wanabe)
In article <4b0081d7e73af_8bc5c2a894735e@redmine.ruby-lang.org>,
[#39709] [Bug #2381] Math.gammaの挙動がx86_64とia64で異なる — Mitsuhiro TAKANO <redmine@...>
Bug #2381: Math.gammaの挙動がx86_64とia64で異なる
[#39714] Net::FTP で upload の resume ができない — Tomoyuki Chikanaga <chikanag@...>
近永と申します。
[#39720] hidden objectって? — keiju@... (Keiju ISHITSUKA)
けいじゅ@いしつかです.
まつもと ゆきひろです
けいじゅ@いしつかです.
まつもと ゆきひろです
けいじゅ@いしつかです.
以下のコミット以降、後述の現象が発生するそうです。
[#39743] String::gsubにおけるinvalid byte sequenceの検出について — TAKEGAWA Hiroshi <takegawa@...>
竹川と申します。
[#39755] RbConfig.rubybin — Tanaka Akira <akr@...>
ruby コマンドのパス名を返す RbConfig.rubybin というメソッド
須藤です。
In article <20091123.123808.1122146273169400964.kou@cozmixng.org>,
> In article <20091123.123808.1122146273169400964.kou@cozmixng.org>,
At Mon, 30 Nov 2009 19:28:39 +0900,
[#39760] [Bug #2395] 可視性の変更による alias されたメソッドの無効化 — _ wanabe <redmine@...>
Bug #2395: 可視性の変更による alias されたメソッドの無効化
[#39796] バグ? ブロック引数で to_ary が呼ばれる必要のない場面で呼ばれる — keiju@... (Keiju ISHITSUKA)
けいじゅ@いしつかです.
まつもと ゆきひろです
けいじゅ@いしつかです.
まつもと ゆきひろです
けいじゅ@いしつかです.
まつもと ゆきひろです
けいじゅ@いしつかです.
まつもと ゆきひろです
[ruby-dev:39685] [Feature #2366] private constant
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