Hi,

At Thu, 5 Apr 2007 08:51:10 +0900,
David Flanagan wrote in [ruby-core:10867]:
> The behavior of the defined? operator is different in current ruby 1.9 
> snapshots than it is in 1.8.5.  Anyone know whether this is a bug or a 
> feature?

Bug.


Index: compile.c =================================================================== --- compile.c (revision 12147) +++ compile.c (working copy) @@ -2049,6 +2049,29 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHO estr = "false"; break; + + case NODE_ARRAY:{ + LABEL *lfalse = NULL; + NODE *vals = node; + + do { + NODE *val = vals->nd_head; + defined_expr(iseq, ret, vals->nd_head, lfinish, Qfalse); + if (lfalse) { + ADD_INSNL(ret, nd_line(node), branchunless, lfalse); + } + else { + LABEL *lcont = NEW_LABEL(nd_line(node)); + ADD_INSNL(ret, nd_line(node), branchif, lcont); + lfalse = NEW_LABEL(nd_line(node)); + ADD_LABEL(ret, lfalse); + ADD_INSN(ret, nd_line(node), putnil); + ADD_INSNL(ret, nd_line(node), jump, lfinish); + ADD_LABEL(ret, lcont); + } + } while (vals = vals->nd_next); + } case NODE_STR: case NODE_LIT: + case NODE_ZARRAY: estr = "expression"; break; @@ -2121,9 +2144,28 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHO case NODE_VCALL: case NODE_FCALL: - if (nd_type(node) == NODE_CALL) { + case NODE_ATTRASGN:{ + LABEL *lfalse = NULL; + int self = Qtrue; + + switch (nd_type(node)) { + case NODE_ATTRASGN: + lfalse = NEW_LABEL(nd_line(node)); + defined_expr(iseq, ret, node->nd_args, lfinish, Qfalse); + if (node->nd_recv == (NODE *)1) break; + case NODE_CALL: + self = Qfalse; + break; + } + if (!self) { LABEL *lcont = NEW_LABEL(nd_line(node)); + if (lfalse) { + ADD_INSNL(ret, nd_line(node), branchunless, lfalse); + } defined_expr(iseq, ret, node->nd_recv, lfinish, Qfalse); ADD_INSNL(ret, nd_line(node), branchif, lcont) ; + if (lfalse) { + ADD_LABEL(ret, lfalse); + } ADD_INSN(ret, nd_line(node), putnil); ADD_INSNL(ret, nd_line(node), jump, lfinish); @@ -2138,6 +2180,14 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHO ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_FUNC), ID2SYM(node->nd_mid), needstr); + if (lfalse) { + ADD_INSNL(ret, nd_line(node), branchif, lfinish); + + ADD_LABEL(ret, lfalse); + ADD_INSN(ret, nd_line(node), putnil); + ADD_INSNL(ret, nd_line(node), jump, lfinish); + } } return 1; + } case NODE_YIELD: @@ -2159,4 +2209,18 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHO return 1; + case NODE_OP_ASGN1: + case NODE_OP_ASGN2: + case NODE_MASGN: + case NODE_LASGN: + case NODE_DASGN: + case NODE_DASGN_CURR: + case NODE_GASGN: + case NODE_IASGN: + case NODE_CDECL: + case NODE_CVDECL: + case NODE_CVASGN: + estr = "assignment"; + break; + default:{ LABEL *lstart = NEW_LABEL(nd_line(node)); @@ -2179,5 +2243,5 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHO ADD_INSNL(ret, nd_line(node), jump, lend); ADD_LABEL(ret, ldefed); - ADD_INSN1(ret, nd_line(node), putobject, str); + ADD_INSN1(ret, nd_line(node), putstring, str); ADD_LABEL(ret, lend);
-- Nobu Nakada