[#23357] [Feature #1432] decrement and increment — Oleg Puchinin <redmine@...>
Feature #1432: decrement and increment
[#23372] [Bug #1438] dylib architecture error building 1.9.1-rc2 on osx10.5.6 — Matthew Moss <redmine@...>
Bug #1438: dylib architecture error building 1.9.1-rc2 on osx10.5.6
[#23402] [Bug #1448] [patch] Proper handling of recursive arrays — Marc-Andre Lafortune <redmine@...>
Bug #1448: [patch] Proper handling of recursive arrays
[#23449] Submit bugs against 1.9.1? — Robert Klemme <shortcutter@...>
Hi there,
[#23457] [Bug #1471] "Mutual join" deadlock detection faulty in 1.8.6 and 1.8.7 — John Carter <redmine@...>
Bug #1471: "Mutual join" deadlock detection faulty in 1.8.6 and 1.8.7
[#23464] [Feature #1473] Improvements on expect.rb — Luiz Angelo Daros de Luca <redmine@...>
Feature #1473: Improvements on expect.rb
[#23483] [Bug #1478] Ruby archive — Oleg Puchinin <redmine@...>
Bug #1478: Ruby archive
Issue #1478 has been updated by Luis Lavena.
Issue #1478 has been updated by Luis Lavena.
On Fri, Apr 2, 2010 at 17:13, Luis Lavena <redmine@ruby-lang.org> wrote:
> Thanks for your comment.
OK Hiroshi, I read some of the comments earlier in the thread that I
On 5/20/10, Jonathan Nielsen <jonathan@jmnet.us> wrote:
Hi,
(2010/05/22 19:58), Benoit Daloze wrote:
On 22 May 2010 18:40, Urabe Shyouhei wrote:
(2010/05/23 2:38), Benoit Daloze wrote:
On Sat, May 22, 2010 at 1:21 PM, Urabe Shyouhei <shyouhei@ruby-lang.org> wrote:
[#23491] [Bug #1482] Kernel.exec doesn't respect COMSPEC environment variable on Windows — Evgeniy Dolzhenko <redmine@...>
Bug #1482: Kernel.exec doesn't respect COMSPEC environment variable on Windows
[#23492] [Bug #1484] Ruby 1.8.6_p368 and Ruby 1.8.7_p160 have threading regressions — Hans de Graaff <redmine@...>
Bug #1484: Ruby 1.8.6_p368 and Ruby 1.8.7_p160 have threading regressions
[#23499] [Bug #1487] String#each_char must return self — Marc-Andre Lafortune <redmine@...>
Bug #1487: String#each_char must return self
Hi,
On Sat, 23 May 2009 10:20:50 +0900
[#23501] [Bug #1490] DateTime::civil fails with second=59 and fractional second > 0 — Paul Harris <redmine@...>
Bug #1490: DateTime::civil fails with second=59 and fractional second > 0
[#23505] [Bug #1494] tempfile#unlink may silently fail on windows — Nicholas Manning <redmine@...>
Bug #1494: tempfile#unlink may silently fail on windows
Issue #1494 has been updated by Shyouhei Urabe.
Issue #1494 has been updated by Hongli Lai.
[#23520] [Bug #1504] installed ri docu is not where ri actually searches when compiled with program-suffix — Yuki Sonoda <redmine@...>
Bug #1504: installed ri docu is not where ri actually searches when compiled with program-suffix
[#23538] [ANN] RubyKaigi2009: Commiter Invitation — SASADA Koichi <ko1@...>
Hi,
[#23543] a feature for ruby: Kernel#in? — Roger Pack <rogerdpack@...>
Following a discussion on ruby-talk of a few ideas for ruby[1],
Excerpts from rogerdpack's message of Mon May 25 07:41:36 +0300 2009:
> I am pretty opposed to adding #in?; however, it is currently
[#23572] [Bug #1525] Deadlock in Ruby 1.9's VM caused by ConditionVariable.wait and fork? — Hongli Lai <redmine@...>
Bug #1525: Deadlock in Ruby 1.9's VM caused by ConditionVariable.wait and fork?
Issue #1525 has been updated by Eric Wong.
Issue #1525 has been updated by Vanja Bucic.
On Jul 21, 2009, at 9:06 PM, Vanja Bucic wrote:
Issue #1525 has been updated by Vanja Bucic.
Vanja Bucic wrote:
none < wrote:
Issue #1525 has been updated by Nobuyoshi Nakada.
In article <4b03c299d3778_4360404660a1be@redmine.ruby-lang.org>,
In article <87einw55ej.fsf@fsij.org>,
Tanaka Akira wrote:
[#23584] [Bug #1528] setlocale is not initialized causing problems when using iconv — Hans de Graaff <redmine@...>
Bug #1528: setlocale is not initialized causing problems when using iconv
[#23593] Defining #name= at the class level — Gregory Brown <gregory.t.brown@...>
Hi folks,
Hi,
Excerpts from Yukihiro Matsumoto's message of Fri May 29 01:21:19 +0300 2009:
Hi,
[#23595] Meaning of RUBY_PLATFORM — Rick DeNatale <rick.denatale@...>
The RUBY_PLATFORM constant is documented in the latest Pickaxe as "The
On Thu, May 28, 2009 at 3:41 PM, Rick DeNatale <rick.denatale@gmail.com> wrote:
On Thu, May 28, 2009 at 2:52 PM, Luis Lavena <luislavena@gmail.com> wrote:
On Thu, May 28, 2009 at 7:08 PM, Rick DeNatale <rick.denatale@gmail.com> wrote:
On Thu, May 28, 2009 at 7:22 PM, Luis Lavena <luislavena@gmail.com> wrote:
> 1) The guy who wrote the gem fell into the trap of assuming that
Roger Pack wrote:
[#23614] [Bug #1535] Hash#merge! Inside Iterator Can Cause RuntimeError — Run Paint Run Run <redmine@...>
Bug #1535: Hash#merge! Inside Iterator Can Cause RuntimeError
[#23630] Expected Behaviour of Modifying an Iterator in the Block to Which it Yields? — Run Paint Run Run <runrun@...>
Hi,
[#23636] feature request: Directory.dir? — Roger Pack <rogerdpack@...>
For some reason it seems odd to have to do File.dir?
[#23639] [Bug #1541] mingw ssl: Errno::ENOTSOCK: An operation was attempted on something that is not a socket. — Roger Pack <redmine@...>
Bug #1541: mingw ssl: Errno::ENOTSOCK: An operation was attempted on something that is not a socket.
Issue #1541 has been updated by Roger Pack.
[#23644] [Bug #1545] Patches for the Hash Documentation — Run Paint Run Run <redmine@...>
Bug #1545: Patches for the Hash Documentation
Excerpts from message of Sun May 31 06:38:54 +0300 2009:
[#23646] Counterpart to File.extname — Martin DeMello <martindemello@...>
File.extname ought to have a complementary method that gets everything
On Sun, May 31, 2009 at 1:52 AM, Martin DeMello <martindemello@gmail.com> wrote:
On Mon, 1 Jun 2009 03:35:47 +0900
On Mon, Jun 1, 2009 at 6:11 AM, Michael Fellinger <m.fellinger@gmail.com> wrote:
[ruby-core:23406] Re: [Bug #1448] [patch] Proper handling of recursive arrays
Hi,
At Sat, 9 May 2009 11:47:53 +0900,
Marc-Andre Lafortune wrote in [ruby-core:23402]:
> The attached patch fixes all of these problems :-)
But reverts old problems.
$ ./ruby -e 'x={};x[1]=x;y={};y[1]=y; p x==y'
-e:1:in `==': stack level too deep (SystemStackError)
from -e:1:in `=='
from -e:1:in `=='
from -e:1:in `=='
from -e:1:in `=='
from -e:1:in `=='
from -e:1:in `=='
from -e:1:in `=='
from -e:1:in `=='
... 5124 levels...
from -e:1:in `=='
from -e:1:in `=='
from -e:1:in `=='
from -e:1:in `<main>'
Also, note that arg of rb_exec_recursive() is not restricted to
a real VALUE.
> * Last problem:
> There is one more problem that my patch doesn't cover (lack
> of mri-fu): hashes for recursive structures are incorrect. As
> per the official doc, "a.eql? b" should imply "a.hash ==
> b.hash". On the other hand, we have (before or after my
> patch):
> a = [x]
> x.eql? a # ==> true
> a.eql? x # ==> true
> x.hash == a.hash # ==> false, should have same hash
I wonder it may be false positive.
$ ruby -e 'x=[];x<<x;a=[x]; p a, x'
[[[...]]]
[[...]]
But no idea right now.
A patch based on yours.
Index: array.c
===================================================================
--- array.c (revision 23373)
+++ array.c (working copy)
@@ -2729,5 +2729,5 @@ recursive_equal(VALUE ary1, VALUE ary2,
long i;
- if (recur) return Qfalse;
+ if (recur) return Qtrue; /* Subtle! */
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
@@ -2762,5 +2762,5 @@ rb_ary_equal(VALUE ary1, VALUE ary2)
}
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
- return rb_exec_recursive(recursive_equal, ary1, ary2);
+ return rb_exec_recursive_paired(recursive_equal, ary1, ary2);
}
@@ -2770,5 +2770,5 @@ recursive_eql(VALUE ary1, VALUE ary2, in
long i;
- if (recur) return Qfalse;
+ if (recur) return Qtrue; /* Subtle! */
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
@@ -2792,5 +2792,5 @@ rb_ary_eql(VALUE ary1, VALUE ary2)
if (TYPE(ary2) != T_ARRAY) return Qfalse;
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
- return rb_exec_recursive(recursive_eql, ary1, ary2);
+ return rb_exec_recursive_paired(recursive_eql, ary1, ary2);
}
@@ -2859,5 +2859,5 @@ recursive_cmp(VALUE ary1, VALUE ary2, in
long i, len;
- if (recur) return Qnil;
+ if (recur) return Qundef; /* Subtle! */
len = RARRAY_LEN(ary1);
if (len > RARRAY_LEN(ary2)) {
@@ -2901,5 +2901,5 @@ rb_ary_cmp(VALUE ary1, VALUE ary2)
ary2 = to_ary(ary2);
if (ary1 == ary2) return INT2FIX(0);
- v = rb_exec_recursive(recursive_cmp, ary1, ary2);
+ v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2);
if (v != Qundef) return v;
len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
Index: hash.c
===================================================================
--- hash.c (revision 23373)
+++ hash.c (working copy)
@@ -1489,5 +1489,5 @@ hash_equal(VALUE hash1, VALUE hash2, int
data.tbl = RHASH(hash2)->ntbl;
data.eql = eql;
- return rb_exec_recursive(recursive_eql, hash1, (VALUE)&data);
+ return rb_exec_recursive_paired(recursive_eql, hash1, (VALUE)&data);
}
Index: thread.c
===================================================================
--- thread.c (revision 23373)
+++ thread.c (working copy)
@@ -3311,5 +3311,5 @@ static ID recursive_key;
static VALUE
-recursive_check(VALUE hash, VALUE obj)
+recursive_check(VALUE hash, VALUE obj, VALUE paired_obj)
{
if (NIL_P(hash) || TYPE(hash) != T_HASH) {
@@ -3317,10 +3317,23 @@ recursive_check(VALUE hash, VALUE obj)
}
else {
- VALUE list = rb_hash_aref(hash, ID2SYM(rb_frame_this_func()));
+ VALUE sym = ID2SYM(rb_frame_this_func());
+ VALUE list = rb_hash_aref(hash, sym);
+ VALUE pair_list;
if (NIL_P(list) || TYPE(list) != T_HASH)
return Qfalse;
- if (NIL_P(rb_hash_lookup(list, obj)))
+ pair_list = rb_hash_lookup2(list, obj, Qundef);
+ if (pair_list == Qundef)
return Qfalse;
+ if (paired_obj) {
+ if (TYPE(pair_list) != T_HASH) {
+ if (pair_list != paired_obj)
+ return Qfalse;
+ }
+ else {
+ if (NIL_P(rb_hash_lookup(pair_list, paired_obj)))
+ return Qfalse;
+ }
+ }
return Qtrue;
}
@@ -3328,7 +3341,7 @@ recursive_check(VALUE hash, VALUE obj)
static VALUE
-recursive_push(VALUE hash, VALUE obj)
+recursive_push(VALUE hash, VALUE obj, VALUE paired_obj)
{
- VALUE list, sym;
+ VALUE list, sym, pair_list;
sym = ID2SYM(rb_frame_this_func());
@@ -3345,20 +3358,31 @@ recursive_push(VALUE hash, VALUE obj)
rb_hash_aset(hash, sym, list);
}
- rb_hash_aset(list, obj, Qtrue);
+ if (!paired_obj) {
+ rb_hash_aset(list, obj, Qtrue);
+ }
+ else if ((pair_list = rb_hash_lookup2(list, obj, Qundef)) == Qundef) {
+ rb_hash_aset(list, obj, paired_obj);
+ }
+ else {
+ if (TYPE(pair_list) != T_HASH){
+ VALUE other_paired_obj = pair_list;
+ pair_list = rb_hash_new();
+ rb_hash_aset(pair_list, other_paired_obj, Qtrue);
+ rb_hash_aset(list, obj, pair_list);
+ }
+ rb_hash_aset(pair_list, paired_obj, Qtrue);
+ }
return hash;
}
static void
-recursive_pop(VALUE hash, VALUE obj)
+recursive_pop(VALUE hash, VALUE obj, VALUE paired_obj)
{
- VALUE list, sym;
+ VALUE list, sym, pair_list, symname, thrname;
sym = ID2SYM(rb_frame_this_func());
if (NIL_P(hash) || TYPE(hash) != T_HASH) {
- VALUE symname;
- VALUE thrname;
symname = rb_inspect(sym);
thrname = rb_inspect(rb_thread_current());
-
rb_raise(rb_eTypeError, "invalid inspect_tbl hash for %s in %s",
StringValuePtr(symname), StringValuePtr(thrname));
@@ -3366,19 +3390,34 @@ recursive_pop(VALUE hash, VALUE obj)
list = rb_hash_aref(hash, sym);
if (NIL_P(list) || TYPE(list) != T_HASH) {
- VALUE symname = rb_inspect(sym);
- VALUE thrname = rb_inspect(rb_thread_current());
+ symname = rb_inspect(sym);
+ thrname = rb_inspect(rb_thread_current());
rb_raise(rb_eTypeError, "invalid inspect_tbl list for %s in %s",
StringValuePtr(symname), StringValuePtr(thrname));
}
+ if (paired_obj) {
+ pair_list = rb_hash_lookup2(list, obj, Qundef);
+ if (pair_list == Qundef) {
+ symname = rb_inspect(sym);
+ thrname = rb_inspect(rb_thread_current());
+ rb_raise(rb_eTypeError, "invalid inspect_tbl pair_list for %s in %s",
+ StringValuePtr(symname), StringValuePtr(thrname));
+ }
+ if (TYPE(pair_list) == T_HASH) {
+ rb_hash_delete(pair_list, obj);
+ if (!RHASH_EMPTY_P(pair_list)) {
+ return; /* keep hash until is empty */
+ }
+ }
+ }
rb_hash_delete(list, obj);
}
-VALUE
-rb_exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE arg)
+static VALUE
+exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE arg, VALUE pairid)
{
volatile VALUE hash = rb_thread_local_aref(rb_thread_current(), recursive_key);
VALUE objid = rb_obj_id(obj);
- if (recursive_check(hash, objid)) {
+ if (recursive_check(hash, objid, pairid)) {
return (*func) (obj, arg, Qtrue);
}
@@ -3387,5 +3426,5 @@ rb_exec_recursive(VALUE (*func) (VALUE,
int state;
- hash = recursive_push(hash, objid);
+ hash = recursive_push(hash, objid, pairid);
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
@@ -3393,5 +3432,5 @@ rb_exec_recursive(VALUE (*func) (VALUE,
}
POP_TAG();
- recursive_pop(hash, objid);
+ recursive_pop(hash, objid, pairid);
if (state)
JUMP_TAG(state);
@@ -3400,4 +3439,16 @@ rb_exec_recursive(VALUE (*func) (VALUE,
}
+VALUE
+rb_exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE arg)
+{
+ return exec_recursive(func, obj, arg, 0);
+}
+
+VALUE
+rb_exec_recursive_paired(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE arg)
+{
+ return exec_recursive(func, obj, arg, rb_obj_id(arg));
+}
+
/* tracer */
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h (revision 23373)
+++ include/ruby/intern.h (working copy)
@@ -341,4 +341,5 @@ void rb_thread_atfork(void);
void rb_thread_atfork_before_exec(void);
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
+VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int),VALUE,VALUE);
/* file.c */
VALUE rb_file_s_expand_path(int, VALUE *);
--
Nobu Nakada