[#34033] The rights of ruby-core people and Myth of ruby-dev — "NARUSE, Yui" <naruse@...>

Some of you may don't know your rights.

32 messages 2011/01/03
[#34067] Re: The rights of ruby-core people and Myth of ruby-dev — Aaron Patterson <aaron@...> 2011/01/04

On Tue, Jan 04, 2011 at 06:55:47AM +0900, NARUSE, Yui wrote:

[#34043] proposal: gem_prelude needs to die — Ryan Davis <ryand-ruby@...>

I think it is time for gem_prelude to die.

21 messages 2011/01/04
[#34077] Re: proposal: gem_prelude needs to die — Tanaka Akira <akr@...> 2011/01/05

2011/1/4 Ryan Davis <ryand-ruby@zenspider.com>:

[#34091] Moving to Git? — Lucas Nussbaum <lucas@...>

Hi,

87 messages 2011/01/05
[#34099] Re: Moving to Git? — KOSAKI Motohiro <kosaki.motohiro@...> 2011/01/05

> Hi,

[#34103] Re: Moving to Git? — "U.Nakamura" <usa@...> 2011/01/05

Hello,

[#34105] Re: Moving to Git? — Rodrigo Rosenfeld Rosas <rr.rosas@...> 2011/01/05

Em 05-01-2011 13:15, U.Nakamura escreveu:

[#34106] Re: Moving to Git? — "NARUSE, Yui" <naruse@...> 2011/01/05

(2011/01/06 0:46), Rodrigo Rosenfeld Rosas wrote:

[#34112] Re: Moving to Git? — Jon <jon.forums@...> 2011/01/05

> > Well, I guess I can help listing some advantages. Using git:

[#34118] Re: Moving to Git? — mathew <meta@...> 2011/01/05

On Wed, Jan 5, 2011 at 11:28, Jon <jon.forums@gmail.com> wrote:

[#34121] Re: Moving to Git? — Rodrigo Rosenfeld Rosas <rr.rosas@...> 2011/01/05

Em 05-01-2011 17:16, mathew escreveu:

[#34129] Re: Moving to Git? — mathew <meta@...> 2011/01/05

On Wed, Jan 5, 2011 at 13:23, Rodrigo Rosenfeld Rosas

[#34138] Re: Moving to Git? — Czarek <cezary.baginski@...> 2011/01/05

On Thu, Jan 06, 2011 at 06:50:24AM +0900, mathew wrote:

[#34188] Re: Moving to Git? — mathew <meta@...> 2011/01/06

On Wed, Jan 5, 2011 at 17:02, Czarek <cezary.baginski@gmail.com> wrote:

[#34191] Re: Moving to Git? — Lucas Nussbaum <lucas@...> 2011/01/06

On 07/01/11 at 01:05 +0900, mathew wrote:

[#34201] Re: Moving to Git? — mathew <meta@...> 2011/01/06

On Thu, Jan 6, 2011 at 10:36, Lucas Nussbaum <lucas@lucas-nussbaum.net> wrote:

[#34206] Re: Moving to Git? — Lucas Nussbaum <lucas@...> 2011/01/07

On 07/01/11 at 08:07 +0900, mathew wrote:

[#34227] Re: Moving to Git? — mathew <meta@...> 2011/01/07

On Thu, Jan 6, 2011 at 23:50, Lucas Nussbaum <lucas@lucas-nussbaum.net> wrote:

[#34231] Re: Moving to Git? — Daniel Bovensiepen <bovensiepen@...> 2011/01/07

Dear all,

[#34116] Re: Moving to Git? — Yukihiro Matsumoto <matz@...> 2011/01/05

Hi,

[#34117] Re: Moving to Git? — Rodrigo Rosenfeld Rosas <rr.rosas@...> 2011/01/05

What kind of Redmine integration you are talking about? We use Redmine

[#34120] Re: Moving to Git? — Yukihiro Matsumoto <matz@...> 2011/01/05

Hi,

[#34125] Re: Moving to Git? — Nikolai Weibull <now@...> 2011/01/05

On Wed, Jan 5, 2011 at 19:57, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

[#34124] [Ruby 1.9-Bug#4235][Open] svn keywords in code prevent correct building of ruby using git mirror — Stephen Bannasch <redmine@...>

Bug #4235: svn keywords in code prevent correct building of ruby using git mirror

12 messages 2011/01/05

[#34171] [Ruby 1.8-Feature#4239][Open] Let's begin a talk for "1.8.8" -- How's needed for surviving 1.8? — Shota Fukumori <redmine@...>

Feature #4239: Let's begin a talk for "1.8.8" -- How's needed for surviving 1.8?

104 messages 2011/01/06
[#34514] [Ruby 1.8-Feature#4239] Let's begin a talk for "1.8.8" -- How's needed for surviving 1.8? — Zeno Davatz <redmine@...> 2011/01/15

Issue #4239 has been updated by Zeno Davatz.

[#34516] Re: [Ruby 1.8-Feature#4239] Let's begin a talk for "1.8.8" -- How's needed for surviving 1.8? — "NARUSE, Yui" <naruse@...> 2011/01/15

(2011/01/16 0:11), Zeno Davatz wrote:

[#34214] [Ruby 1.9-Feature#4247][Open] New features for Array#sample, Array#choice — Yoji Ojima <redmine@...>

Feature #4247: New features for Array#sample, Array#choice

10 messages 2011/01/07

[#34267] [Ruby 1.9-Feature#4254][Open] Allow method transplanting — Jonas Pfenniger <redmine@...>

Feature #4254: Allow method transplanting

23 messages 2011/01/09
[#34280] Re: [Ruby 1.9-Feature#4254][Open] Allow method transplanting — Yukihiro Matsumoto <matz@...> 2011/01/10

Hi,

[#34299] [Ruby 1.9-Bug#4256][Open] [BUG] Segmentation fault ruby 1.9.2p0 (2010-08-18) [i386-mingw32] — Rama Mahendravada <redmine@...>

Bug #4256: [BUG] Segmentation fault ruby 1.9.2p0 (2010-08-18) [i386-mingw32]

9 messages 2011/01/10

[#34318] ext/bigdecimal/lib/bigdecimal/util.rb — Aaron Patterson <aaron@...>

Hi Murata!

14 messages 2011/01/11
[#34321] Re: ext/bigdecimal/lib/bigdecimal/util.rb — Yukihiro Matsumoto <matz@...> 2011/01/11

Hi,

[#34354] [Ruby 1.9-Feature#4264][Open] General type coercion protocol for Ruby — Charles Nutter <redmine@...>

Feature #4264: General type coercion protocol for Ruby

33 messages 2011/01/11
[#34359] Re: [Ruby 1.9-Feature#4264][Open] General type coercion protocol for Ruby — Jim Weirich <jim.weirich@...> 2011/01/11

[#34355] [Ruby 1.9-Feature#4265][Open] Provide a core method Kernel#ruby for invoking a new Ruby instance — Charles Nutter <redmine@...>

Feature #4265: Provide a core method Kernel#ruby for invoking a new Ruby instance

15 messages 2011/01/11

[#34362] [Ruby 1.9-Bug#4266][Open] Timeouts in threads cause "ThreadError: deadlock; recursive locking" — Christopher Bottaro <redmine@...>

Bug #4266: Timeouts in threads cause "ThreadError: deadlock; recursive locking"

12 messages 2011/01/11

[#34399] [Ruby 1.9-Bug#4272][Open] rb_enc_str_new() causes segmentfault when using threads in parallel — Iñaki Baz Castillo <redmine@...>

Bug #4272: rb_enc_str_new() causes segmentfault when using threads in parallel

14 messages 2011/01/12

[#34534] [Ruby 1.9-Bug#4283][Open] Timeout.timeout may cause application exit unintetionally — Motohiro KOSAKI <redmine@...>

Bug #4283: Timeout.timeout may cause application exit unintetionally

11 messages 2011/01/17

[#34537] [Ruby 1.9-Bug#4285][Open] Ruby don't have asynchrounous exception safe syntax and It should have. — Motohiro KOSAKI <redmine@...>

Bug #4285: Ruby don't have asynchrounous exception safe syntax and It should have.

12 messages 2011/01/17

[#34550] [Ruby 1.9-Feature#4288][Open] Allow invoking arbitrary method names with foo."something" syntax — Charles Nutter <redmine@...>

Feature #4288: Allow invoking arbitrary method names with foo."something" syntax

13 messages 2011/01/18
[#34616] Re: [Ruby 1.9-Feature#4288][Open] Allow invoking arbitrary method names with foo."something" syntax — Gary Wright <gwtmp01@...> 2011/01/19

[#34577] Importing rubygems 1.5.0 (release candidate) into trunk. — Ryan Davis <ryand-ruby@...>

I'm going to be committing rubygems 1.5.0 into trunk in a bit.

13 messages 2011/01/18

[#34632] Ruby operator equivalent to Groovy's "?." — Rodrigo Rosenfeld Rosas <rr.rosas@...>

One of the few things I like in Groovy that Ruby doesn't support is

19 messages 2011/01/20

[#34634] Returning from the callee — Rodrigo Rosenfeld Rosas <rr.rosas@...>

Sometimes it is useful to be able to return from the callee method.

15 messages 2011/01/20

[#34648] [Ruby 1.9-Bug#4298][Open] Duration of calling String#[] with the same index is strangely related to string length. — Radosław Bułat <redmine@...>

Bug #4298: Duration of calling String#[] with the same index is strangely related to string length.

13 messages 2011/01/20

[#34861] [Ruby 1.9-Feature#4326][Open] Fiber should respond to call() and [] — Aaron Patterson <redmine@...>

Feature #4326: Fiber should respond to call() and []

21 messages 2011/01/26
[#34943] [Ruby 1.9-Feature#4326] Fiber should respond to call() and [] — Charles Nutter <redmine@...> 2011/01/28

Issue #4326 has been updated by Charles Nutter.

[#34954] Re: [Ruby 1.9-Feature#4326] Fiber should respond to call() and [] — Aaron Patterson <aaron@...> 2011/01/28

On Sat, Jan 29, 2011 at 02:58:46AM +0900, Charles Nutter wrote:

[#34957] Re: [Ruby 1.9-Feature#4326] Fiber should respond to call() and [] — Charles Oliver Nutter <headius@...> 2011/01/29

On Fri, Jan 28, 2011 at 5:29 PM, Aaron Patterson

[#34869] make ruby support line continuations ? — Marc Chantreux <khatar@...>

hello,

22 messages 2011/01/26
[#34878] Re: make ruby support line continuations ? — Jim Freeze <jimfreeze@...> 2011/01/26

> I love it so much i tried it in ruby. trying to rewrite:

[#34887] Re: make ruby support line continuations ? — Marc Chantreux <khatar@...> 2011/01/27

hello,

[#34889] Re: make ruby support line continuations ? — V咜 Ondruch <v.ondruch@...> 2011/01/27

Dne 27.1.2011 7:15, Marc Chantreux napsal(a):

[#34911] The ruby-lang.org downloads page should include RVM for OS X — Andrew Vos <andrew.vos@...>

(I sent this before I subscribed and I'm not sure if it bounced. Sorry if

21 messages 2011/01/27
[#34912] Re: The ruby-lang.org downloads page should include RVM for OS X — "Shota Fukumori (sora_h)" <sorah@...> 2011/01/27

RVM is not official, and makes problem more difficult. (magically

[#34913] Re: The ruby-lang.org downloads page should include RVM for OS X — Andrew Vos <andrew.vos@...> 2011/01/27

What do you mean by "official"? Also, what does it make more difficult? Do

[#34914] Re: The ruby-lang.org downloads page should include RVM for OS X — "Shota Fukumori (sora_h)" <sorah@...> 2011/01/27

return mail is gmail thing. I have same problem.

[#34970] [Ruby 1.9-Bug#4343][Open] Dir.glob does match files without extension — Vit Ondruch <redmine@...>

Bug #4343: Dir.glob does match files without extension

26 messages 2011/01/29
[#34975] [Ruby 1.9-Bug#4343] Dir.glob does match files without extension — Nobuyoshi Nakada <redmine@...> 2011/01/29

Issue #4343 has been updated by Nobuyoshi Nakada.

[#34978] Re: [Ruby 1.9-Bug#4343] Dir.glob does match files without extension — Jeremy Bopp <jeremy@...> 2011/01/29

On 01/29/2011 10:19 AM, Nobuyoshi Nakada wrote:

[#34979] Re: [Ruby 1.9-Bug#4343] Dir.glob does match files without extension — Vít Ondruch <v.ondruch@...> 2011/01/29

Dne 29.1.2011 17:27, Jeremy Bopp napsal(a):

[#34981] Re: [Ruby 1.9-Bug#4343] Dir.glob does match files without extension — Jeremy Bopp <jeremy@...> 2011/01/29

On 01/29/2011 10:33 AM, Vテュt Ondruch wrote:

[#34982] Re: [Ruby 1.9-Bug#4343] Dir.glob does match files without extension — Vít Ondruch <v.ondruch@...> 2011/01/29

Dne 29.1.2011 17:53, Jeremy Bopp napsal(a):

[ruby-core:34967] Re: [Ruby 1.9-Feature#3908][Assigned] private constant

From: Yusuke ENDOH <mame@...>
Date: 2011-01-29 03:07:28 UTC
List: ruby-core #34967
Hi, matz

May I introduce these methods in relation to private constants?

  - Module#public_constants, as alias to Module#constants
    (corresponding to Ojbect#public_methods)

  - Module#private_constants, which returns an array that contains
    only private constant names.
    (corresponding to Ojbect#private_methods)

  - Module#public_const_get, which return the constant value or
    raise a NameError if the constant is private
    (corresponding to Object#public_send)

  - Module#public_const_defined?, which tells whether the public
    constant is defined or not
    (corresponding to Module#public_method_defined?)

  - Module#private_const_defined?, which tells whether the private
    constant is defined or not
    (corresponding to Module#private_method_defined?)

A patch and tests are attached.  Thank you.



Note: I fixed other bugs which RPRR and nagachika reported (r30713,
r30714, r30715, r30716 and r30718).  Sorry for late action.


2010/12/22 Yusuke Endoh <redmine@ruby-lang.org>:
> Issue #3908 has been updated by Yusuke Endoh.
>
> Status changed from Closed to Assigned
>
> Hi, NaHi
>
>> Just as a notification since I see this ticket closed today.
>
> Kazu committed a change of NEWS with ML ref, which closed this
> ticket.  think that he did not intend to close this ticket.
> That is, it is just accident. 'm reopening this ticket.
>
>
>> Yusuke, patches in the mail I'm replying are not applied
>
> Yes, just because of my laziness.  will work on.
>
>
>> and we still need discuss about followings, right?
>
> I think that what we needed is not discussion, but matz's final
> approval.
> The reason why this ticket stopped was because matz cancelled
> his approval and opposed this feature at [ruby-dev:42469].
> And, matz has finally re-approved it at [ruby-dev:42587].
> So we can now move on.
>
>
>> - Module#constants includes a private constant?
>
> It should not.  will.
>
>
>> - Module#const_get raises NameError for a private constant?
>
> It should not.  will.
>
>
>> - add Module#public_constants and Module#private_constants?
>
> Plus, Module#public_const_get. ut these may be need matz's
> additional approval.
>
>
> Matz, can I add these methods:
>
>  Module#public_constants, which returns an array that contains
> nly public constant names.
>
>  Module#private_constants, which returns an array that contatins
> nly private constant names.
>
>  Module#public_const_get, which returns a value assigned to the
> onstant if it is public, or raise a NameError if it is private.
>
> ?
>
>
>> - Module#const_set changes the constant visibility to public? Setting
> visibility via const_set?
>
> It is just a bug.  will.
>
> --
> Yusuke Endoh <mame@tsg.ne.jp>
> ----------------------------------------
> http://redmine.ruby-lang.org/issues/show/3908
>
> ----------------------------------------
> http://redmine.ruby-lang.org


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

Attachments (1)

private-constant-omake.patch (11.6 KB, text/x-diff)
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index 1e3a01b..5088b12 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -852,6 +852,7 @@ void *rb_mod_const_at(VALUE, void*);
 void *rb_mod_const_of(VALUE, void*);
 VALUE rb_const_list(void*);
 VALUE rb_mod_constants(int, VALUE *, VALUE);
+VALUE rb_mod_private_constants(int, VALUE *, VALUE);
 VALUE rb_mod_remove_const(VALUE, VALUE);
 int rb_const_defined(VALUE, ID);
 int rb_const_defined_at(VALUE, ID);
diff --git a/object.c b/object.c
index b25c0af..6856e14 100644
--- a/object.c
+++ b/object.c
@@ -1686,20 +1686,8 @@ rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass)
     return Qnil;
 }
 
-/*
- *  call-seq:
- *     mod.const_get(sym, inherit=true)    -> obj
- *
- *  Returns the value of the named constant in <i>mod</i>.
- *
- *     Math.const_get(:PI)   #=> 3.14159265358979
- *
- *  If the constant is not defined or is defined by the ancestors and
- *  +inherit+ is false, +NameError+ will be raised.
- */
-
 static VALUE
-rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
+mod_const_get(int argc, VALUE *argv, VALUE mod, VALUE visibility)
 {
     VALUE name, recur;
     ID id;
@@ -1715,11 +1703,52 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
     if (!rb_is_const_id(id)) {
 	rb_name_error(id, "wrong constant name %s", rb_id2name(id));
     }
+    if (visibility) {
+	return RTEST(recur) ? rb_public_const_get(mod, id) : rb_public_const_get_at(mod, id);
+    }
     return RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id);
 }
 
 /*
  *  call-seq:
+ *     mod.const_get(sym, inherit=true)    -> obj
+ *
+ *  Returns the value of the named constant in <i>mod</i>.
+ *
+ *     Math.const_get(:PI)   #=> 3.14159265358979
+ *
+ *  If the constant is not defined or is defined by the ancestors and
+ *  +inherit+ is false, +NameError+ will be raised.
+ *  This method returns the value even if the constant is private.
+ */
+
+static VALUE
+rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
+{
+    mod_const_get(argc, argv, mod, FALSE);
+}
+
+/*
+ *  call-seq:
+ *     mod.public_const_get(sym, inherit=true)    -> obj
+ *
+ *  Returns the value of the named constant in <i>mod</i>.
+ *
+ *     Math.public_const_get(:PI)   #=> 3.14159265358979
+ *
+ *  If the constant is not defined or is defined by the ancestors and
+ *  +inherit+ is false, +NameError+ will be raised.
+ *  +NameError+ will also be raised if the constant is private.
+ */
+
+static VALUE
+rb_mod_public_const_get(int argc, VALUE *argv, VALUE mod)
+{
+    mod_const_get(argc, argv, mod, TRUE);
+}
+
+/*
+ *  call-seq:
  *     mod.const_set(sym, obj)    -> obj
  *
  *  Sets the named constant to the given object, returning that object.
@@ -1742,20 +1771,8 @@ rb_mod_const_set(VALUE mod, VALUE name, VALUE value)
     return value;
 }
 
-/*
- *  call-seq:
- *     mod.const_defined?(sym, inherit=true)   -> true or false
- *
- *  Returns <code>true</code> if a constant with the given name is
- *  defined by <i>mod</i>, or its ancestors if +inherit+ is not false.
- *
- *     Math.const_defined? "PI"   #=> true
- *     IO.const_defined? "SYNC"   #=> true
- *     IO.const_defined? "SYNC", false   #=> false
- */
-
 static VALUE
-rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
+mod_const_defined(int argc, VALUE *argv, VALUE mod, int visibility)
 {
     VALUE name, recur;
     ID id;
@@ -1771,7 +1788,75 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
     if (!rb_is_const_id(id)) {
 	rb_name_error(id, "wrong constant name %s", rb_id2name(id));
     }
-    return RTEST(recur) ? rb_const_defined(mod, id) : rb_const_defined_at(mod, id);
+    switch (visibility) {
+      case 0:
+	return RTEST(recur) ? rb_const_defined(mod, id) : rb_const_defined_at(mod, id);
+      case 1:
+	return RTEST(recur) ? rb_public_const_defined(mod, id) : rb_public_const_defined_at(mod, id);
+    }
+    if (RTEST(recur)) {
+	return RTEST(rb_const_defined(mod, id)) && !RTEST(rb_public_const_defined(mod, id)) ? Qtrue : Qfalse;
+    }
+    return RTEST(rb_const_defined_at(mod, id)) && !RTEST(rb_public_const_defined_at(mod, id)) ? Qtrue : Qfalse;
+}
+
+/*
+ *  call-seq:
+ *     mod.const_defined?(sym, inherit=true)   -> true or false
+ *
+ *  Returns <code>true</code> if a constant with the given name is
+ *  defined by <i>mod</i>, or its ancestors if +inherit+ is not false,
+ *  regardless of whether the constant is public or private.
+ *
+ *     Math.const_defined? "PI"   #=> true
+ *     IO.const_defined? "SYNC"   #=> true
+ *     IO.const_defined? "SYNC", false   #=> false
+ */
+
+static VALUE
+rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
+{
+    mod_const_defined(argc, argv, mod, 0);
+}
+
+/*
+ *  call-seq:
+ *     mod.public_const_defined?(sym, inherit=true)   -> true or false
+ *
+ *  Returns <code>true</code> if a public constant with the given name is
+ *  defined by <i>mod</i>, or its ancestors if +inherit+ is not false.
+ *
+ *     module Math
+ *       private_constant :E
+ *     end
+ *     Math.public_const_defined? "PI"   #=> true
+ *     Math.public_const_defined? "E"    #=> false
+ */
+
+static VALUE
+rb_mod_public_const_defined(int argc, VALUE *argv, VALUE mod)
+{
+    mod_const_defined(argc, argv, mod, 1);
+}
+
+/*
+ *  call-seq:
+ *     mod.private_const_defined?(sym, inherit=true)   -> true or false
+ *
+ *  Returns <code>true</code> if a private constant with the given name is
+ *  defined by <i>mod</i>, or its ancestors if +inherit+ is not false.
+ *
+ *     module Math
+ *       private_constant :E
+ *     end
+ *     Math.private_const_defined? "PI"   #=> false
+ *     Math.private_const_defined? "E"    #=> true
+ */
+
+static VALUE
+rb_mod_private_const_defined(int argc, VALUE *argv, VALUE mod)
+{
+    mod_const_defined(argc, argv, mod, 2);
 }
 
 VALUE rb_obj_methods(int argc, VALUE *argv, VALUE obj);
@@ -2638,9 +2723,14 @@ Init_Object(void)
 		     rb_class_private_instance_methods, -1);   /* in class.c */
 
     rb_define_method(rb_cModule, "constants", rb_mod_constants, -1); /* in variable.c */
+    rb_define_method(rb_cModule, "public_constants", rb_mod_constants, -1); /* in variable.c */
+    rb_define_method(rb_cModule, "private_constants", rb_mod_private_constants, -1); /* in variable.c */
     rb_define_method(rb_cModule, "const_get", rb_mod_const_get, -1);
+    rb_define_method(rb_cModule, "public_const_get", rb_mod_public_const_get, -1);
     rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2);
     rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, -1);
+    rb_define_method(rb_cModule, "public_const_defined?", rb_mod_public_const_defined, -1);
+    rb_define_method(rb_cModule, "private_const_defined?", rb_mod_private_const_defined, -1);
     rb_define_private_method(rb_cModule, "remove_const",
 			     rb_mod_remove_const, 1); /* in variable.c */
     rb_define_method(rb_cModule, "const_missing",
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index ce6e8a6..e58c260 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -982,8 +982,48 @@ class TestModule < Test::Unit::TestCase
     assert_equal("foo", c::FOO)
   end
 
+  module ConstTest
+    PublicConstant = :public
+    PrivateConstant = :private
+    private_constant :PrivateConstant
+  end
+
   def test_constants_with_private_constant
     assert(!(::TestModule).constants.include?(:PrivateClass))
+    assert_equal([:PublicConstant], ConstTest.constants)
+  end
+
+  def test_public_constants
+    assert_equal([:PublicConstant], ConstTest.public_constants)
+  end
+
+  def test_private_constants
+    assert_equal([:PrivateConstant], ConstTest.private_constants)
+  end
+
+  def test_const_defined_with_private_constant
+    assert_equal(true, ConstTest.const_defined?(:PublicConstant))
+    assert_equal(true, ConstTest.const_defined?(:PrivateConstant))
+  end
+
+  def test_public_const_defined?
+    assert_equal(true, ConstTest.public_const_defined?(:PublicConstant))
+    assert_equal(false, ConstTest.public_const_defined?(:PrivateConstant))
+  end
+
+  def test_private_const_defined?
+    assert_equal(false, ConstTest.private_const_defined?(:PublicConstant))
+    assert_equal(true, ConstTest.private_const_defined?(:PrivateConstant))
+  end
+
+  def test_const_get_with_private_constant
+    assert_equal(:public, ConstTest.const_get(:PublicConstant))
+    assert_equal(:private, ConstTest.const_get(:PrivateConstant))
+  end
+
+  def test_public_const_get
+    assert_equal(:public, ConstTest.public_const_get(:PublicConstant))
+    assert_raise(NameError) { ConstTest.public_const_get(:PrivateConstant) }
   end
 
   def test_toplevel_private_constant
diff --git a/variable.c b/variable.c
index daaf4e2..5f5b5ff 100644
--- a/variable.c
+++ b/variable.c
@@ -1742,11 +1742,11 @@ rb_mod_const_of(VALUE mod, void *data)
 }
 
 static int
-list_i(st_data_t key, st_data_t value, VALUE ary)
+list_i(st_data_t key, st_data_t value, VALUE *args)
 {
     ID sym = (ID)key;
     rb_const_entry_t *ce = (rb_const_entry_t *)value;
-    if (ce->flag != CONST_PRIVATE) rb_ary_push(ary, ID2SYM(sym));
+    if (args[1] == (ce->flag != CONST_PRIVATE)) rb_ary_push(args[0], ID2SYM(sym));
     return ST_CONTINUE;
 }
 
@@ -1754,22 +1754,52 @@ VALUE
 rb_const_list(void *data)
 {
     st_table *tbl = data;
-    VALUE ary;
+    VALUE args[2];
 
     if (!tbl) return rb_ary_new2(0);
-    ary = rb_ary_new2(tbl->num_entries);
-    st_foreach_safe(tbl, list_i, ary);
+    args[0] = rb_ary_new2(tbl->num_entries);
+    args[1] = TRUE;
+    st_foreach_safe(tbl, list_i, args);
     st_free_table(tbl);
 
-    return ary;
+    return args[0];
+}
+
+static VALUE
+mod_constants(int argc, VALUE *argv, VALUE mod, VALUE visibility)
+{
+    VALUE inherit, args[2];
+    st_table *tbl;
+
+    if (argc == 0) {
+	inherit = Qtrue;
+    }
+    else {
+	rb_scan_args(argc, argv, "01", &inherit);
+    }
+    if (RTEST(inherit)) {
+	tbl = rb_mod_const_of(mod, 0);
+    }
+    else {
+	tbl = rb_mod_const_at(mod, 0);
+    }
+
+    if (!tbl) return rb_ary_new2(0);
+    args[0] = rb_ary_new2(tbl->num_entries);
+    args[1] = visibility;
+    st_foreach_safe(tbl, list_i, args);
+    st_free_table(tbl);
+
+    return args[0];
 }
 
 /*
  *  call-seq:
  *     mod.constants(inherit=true)    -> array
+ *     mod.public_constants(inherit=true)    -> array
  *
- *  Returns an array of the names of the constants accessible in
- *  <i>mod</i>. This includes the names of constants in any included
+ *  Returns an array of the names of the public constants accessible in
+ *  <i>mod</i>. This includes the names of public constants in any included
  *  modules (example at start of section), unless the <i>all</i>
  *  parameter is set to <code>false</code>.
  *
@@ -1782,22 +1812,28 @@ rb_const_list(void *data)
 VALUE
 rb_mod_constants(int argc, VALUE *argv, VALUE mod)
 {
-    VALUE inherit;
-    st_table *tbl;
+    return mod_constants(argc, argv, mod, TRUE);
+}
 
-    if (argc == 0) {
-	inherit = Qtrue;
-    }
-    else {
-	rb_scan_args(argc, argv, "01", &inherit);
-    }
-    if (RTEST(inherit)) {
-	tbl = rb_mod_const_of(mod, 0);
-    }
-    else {
-	tbl = rb_mod_const_at(mod, 0);
-    }
-    return rb_const_list(tbl);
+/*
+ *  call-seq:
+ *     mod.private_constants(inherit=true)    -> array
+ *
+ *  Returns an array of the names of the private constants accessible in
+ *  <i>mod</i>. This includes the names of private constants in any included
+ *  modules (example at start of section), unless the <i>all</i>
+ *  parameter is set to <code>false</code>.
+ *
+ *    IO.private_constants.include?(:SYNC)        #=> false
+ *    IO.private_constants(false).include?(:SYNC) #=> false
+ *
+ *  Also see <code>Module::const_defined?</code>.
+ */
+
+VALUE
+rb_mod_private_constants(int argc, VALUE *argv, VALUE mod)
+{
+    return mod_constants(argc, argv, mod, FALSE);
 }
 
 static int

In This Thread

Prev Next