[#21709] [Feature #1084] request for: Array#sort_by! — Radosław Bułat <redmine@...>

Feature #1084: request for: Array#sort_by!

15 messages 2009/02/01

[#21714] [BUG:trunk] Got the error message, after run 'gem install --test'. — Takao Kouji <kouji@...7.net>

Hi, Ryan.

14 messages 2009/02/01

[#21715] New documentation system! — Luiz Vitor Martinez Cardoso <grabber@...>

People,

35 messages 2009/02/01
[#21716] Re: New documentation system! — Austin Ziegler <halostatue@...> 2009/02/01

On Sun, Feb 1, 2009 at 10:51 AM, Luiz Vitor Martinez Cardoso

[#21717] Re: New documentation system! — znmeb@... 2009/02/01

Quoting Austin Ziegler <halostatue@gmail.com>:

[#21718] Re: New documentation system! — Luiz Vitor Martinez Cardoso <grabber@...> 2009/02/01

People,

[#21719] Re: New documentation system! — Yehuda Katz <wycats@...> 2009/02/01

One project that has been in the works for a while and shows a lot of

[#21731] Re: New documentation system! — Charles Oliver Nutter <charles.nutter@...> 2009/02/02

I'd love to see a documentation system similar to what python has, and

[#21746] Re: New documentation system! — Luiz Vitor Martinez Cardoso <grabber@...> 2009/02/02

People,

[#21754] Re: New documentation system! — Charles Oliver Nutter <charles.nutter@...> 2009/02/02

Luiz Vitor Martinez Cardoso wrote:

[#21802] [Bug #1098] Unclear encoding error: #<Encoding::UndefinedConversionError: "\xE2\x96\x80" from UTF-8 to ISO-8859-1 in conversion from CP850 to ISO-8859-1> — Tom Link <redmine@...>

Bug #1098: Unclear encoding error: #<Encoding::UndefinedConversionError: "\xE2\x96\x80" from UTF-8 to ISO-8859-1 in conversion from CP850 to ISO-8859-1>

6 messages 2009/02/03

[#21893] [Feature #1122] request for: Object#try — Narihiro Nakamura <redmine@...>

Feature #1122: request for: Object#try

30 messages 2009/02/06
[#21907] Re: [Feature #1122] request for: Object#try — Yusuke ENDOH <mame@...> 2009/02/07

Hi,

[#21909] Re: [Feature #1122] request for: Object#try — "David A. Black" <dblack@...> 2009/02/07

Hi --

[#21923] Re: [Feature #1122] request for: Object#try — Yusuke ENDOH <mame@...> 2009/02/08

Hi,

[#21932] Re: [Feature #1122] request for: Object#try — "David A. Black" <dblack@...> 2009/02/08

Hi--

[#21968] Re: [Feature #1122] request for: Object#try — Michal Babej <calcifer@...> 2009/02/10

Hi,

[#21972] Re: [Feature #1122] request for: Object#try — "David A. Black" <dblack@...> 2009/02/10

Hi --

[#21973] Re: [Feature #1122] request for: Object#try — =?ISO-8859-2?Q?Rados=B3aw_Bu=B3at?= <radek.bulat@...> 2009/02/11

Providing new syntax change for such a small thing is IMHO

[#22165] Re: [Feature #1122] request for: Object#try — Yehuda Katz <wycats@...> 2009/02/15

Count me in as a +1 on foo.?bar(baz). I'm on the fence about whether ?bar

[#22177] Re: [Feature #1122] request for: Object#try — Daniel Luz <dev@...> 2009/02/16

2009/2/15 Yehuda Katz <wycats@gmail.com>:

[#22219] Re: [Feature #1122] request for: Object#try — Roger Pack <rogerdpack@...> 2009/02/18

> IMHO, foo.?bar should behave as "call-except-if-nil". Not only it

[#22226] Re: [Feature #1122] request for: Object#try — =?ISO-8859-2?Q?Rados=B3aw_Bu=B3at?= <radek.bulat@...> 2009/02/18

On Wed, Feb 18, 2009 at 6:29 PM, Roger Pack <rogerdpack@gmail.com> wrote:

[#22230] Re: [Feature #1122] request for: Object#try — Roger Pack <rogerdpack@...> 2009/02/18

> Then how it is different from

[#21903] [Bug #1127] error while compiling Win32API under MinGW — Luis Lavena <redmine@...>

Bug #1127: error while compiling Win32API under MinGW

15 messages 2009/02/07

[#21937] [Bug #1131] String#unpack("V") does not work correctly is linux on s390x — Ittay Dror <redmine@...>

Bug #1131: String#unpack("V") does not work correctly is linux on s390x

13 messages 2009/02/08

[#21946] New hash : syntax for the 1.8 series? — Brent Roman <brent@...>

36 messages 2009/02/10
[#21949] Re: New hash : syntax for the 1.8 series? — "Akinori MUSHA" <knu@...> 2009/02/10

At Tue, 10 Feb 2009 16:30:55 +0900,

[#21952] Re: New hash : syntax for the 1.8 series? — "David A. Black" <dblack@...> 2009/02/10

Hi --

[#21963] Re: New hash : syntax for the 1.8 series? — "Akinori MUSHA" <knu@...> 2009/02/10

At Tue, 10 Feb 2009 22:32:19 +0900,

[#21977] Re: New hash : syntax for the 1.8 series? — Evan Phoenix <evan@...> 2009/02/11

[#21980] Re: New hash : syntax for the 1.8 series? — Yukihiro Matsumoto <matz@...> 2009/02/11

Hi,

[#21997] 1.8.7 Specifics — John Barnette <jbarnette@...>

There's a fair amount of talk lately about release management and

80 messages 2009/02/11
[#21999] Re: 1.8.7 Specifics — Luis Lavena <luislavena@...> 2009/02/11

On Wed, Feb 11, 2009 at 4:42 PM, John Barnette <jbarnette@gmail.com> wrote:

[#22004] Re: 1.8.7 Specifics — Charles Oliver Nutter <charles.nutter@...> 2009/02/11

Luis Lavena wrote:

[#22005] Re: 1.8.7 Specifics — Luis Lavena <luislavena@...> 2009/02/11

On Wed, Feb 11, 2009 at 5:55 PM, Charles Oliver Nutter

[#22007] Re: 1.8.7 Specifics — Pit Capitain <pit.capitain@...> 2009/02/11

2009/2/11 Luis Lavena <luislavena@gmail.com>:

[#22008] Re: 1.8.7 Specifics — Yukihiro Matsumoto <matz@...> 2009/02/11

Hi,

[#22024] Re: 1.8.7 Specifics — Brent Roman <brent@...> 2009/02/12

[#22025] Re: 1.8.7 Specifics — Yukihiro Matsumoto <matz@...> 2009/02/12

Hi,

[#22028] Re: 1.8.7 Specifics — Ezra Zygmuntowicz <ezmobius@...> 2009/02/12

[#22048] Re: 1.8.7 Specifics — Urabe Shyouhei <shyouhei@...> 2009/02/13

Hello Ezra,

[#22049] Re: 1.8.7 Specifics — Ezra Zygmuntowicz <ezmobius@...> 2009/02/13

[#22051] A short memorandum (Re: 1.8.7 Specifics) — Urabe Shyouhei <shyouhei@...> 2009/02/13

Let me leave a memo to remember issues I can think of.

[#22054] Re: A short memorandum (Re: 1.8.7 Specifics) — Charles Oliver Nutter <charles.nutter@...> 2009/02/13

Urabe Shyouhei wrote:

[#22055] Re: A short memorandum (Re: 1.8.7 Specifics) — Charles Oliver Nutter <charles.nutter@...> 2009/02/13

Charles Oliver Nutter wrote:

[#22079] Re: A short memorandum (Re: 1.8.7 Specifics) — Eero Saynatkari <ruby-ml@...> 2009/02/14

Excerpts from Headius: Charles Oliver Nutter's message of Sat Feb 14 00:53:17 +0200 2009:

[#22091] Re: A short memorandum (Re: 1.8.7 Specifics) — Charles Oliver Nutter <charles.nutter@...> 2009/02/14

Eero Saynatkari wrote:

[#22101] Re: A short memorandum (Re: 1.8.7 Specifics) — Urabe Shyouhei <shyouhei@...> 2009/02/14

Charles Oliver Nutter wrote:

[#22107] Re: A short memorandum (Re: 1.8.7 Specifics) — Ezra Zygmuntowicz <ezmobius@...> 2009/02/14

[#22123] Re: A short memorandum (Re: 1.8.7 Specifics) — Urabe Shyouhei <shyouhei@...> 2009/02/14

Ezra Zygmuntowicz wrote:

[#22128] Re: A short memorandum (Re: 1.8.7 Specifics) — Nobuyoshi Nakada <nobu@...> 2009/02/15

Hi,

[#22132] Re: A short memorandum (Re: 1.8.7 Specifics) — Brent Roman <brent@...> 2009/02/15

[#22139] Re: A short memorandum (Re: 1.8.7 Specifics) — Charles Oliver Nutter <charles.nutter@...> 2009/02/15

Brent Roman wrote:

[#22145] Re: A short memorandum (Re: 1.8.7 Specifics) — Brent Roman <brent@...> 2009/02/15

[#22152] Re: A short memorandum (Re: 1.8.7 Specifics) — Charles Oliver Nutter <charles.nutter@...> 2009/02/15

Brent Roman wrote:

[#22065] Dir.glob and duplicates? — Charles Oliver Nutter <charles.nutter@...>

I was fixing a JRuby Dir.glob spec failure where we produced a duplicate

28 messages 2009/02/14
[#22066] Re: Dir.glob and duplicates? — Tanaka Akira <akr@...> 2009/02/14

In article <4996749D.7050009@sun.com>,

[#22116] [Bug #1162] Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderr — Charlie Savage <redmine@...>

Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderr

11 messages 2009/02/14

[#22206] ruby-1.9.1-p0 build failure on i586 — "Jeroen van Meeuwen (Fedora Project)" <kanarip@...>

Hi there,

12 messages 2009/02/18

[#22212] [Bug #1172] [sparc] *** glibc detected *** ruby1.9: free(): invalid pointer: 0xf7ef6a54 *** — Lucas Nussbaum <redmine@...>

Bug #1172: [sparc] *** glibc detected *** ruby1.9: free(): invalid pointer: 0xf7ef6a54 ***

12 messages 2009/02/18

[#22246] YASNP (Yet Another Selector Namespace Proposal) — Yehuda Katz <wycats@...>

The idea is to make selectors like optional versions of Python imports.

137 messages 2009/02/19
[#22251] Re: YASNP (Yet Another Selector Namespace Proposal) — Charles Oliver Nutter <charles.nutter@...> 2009/02/19

Yehuda Katz wrote:

[#22252] Re: YASNP (Yet Another Selector Namespace Proposal) — Charles Oliver Nutter <charles.nutter@...> 2009/02/19

Charles Oliver Nutter wrote:

[#22262] Re: YASNP (Yet Another Selector Namespace Proposal) — Florian Gilcher <flo@...> 2009/02/19

[#22267] Re: YASNP (Yet Another Selector Namespace Proposal) — Yehuda Katz <wycats@...> 2009/02/19

2009/2/19 Florian Gilcher <flo@andersground.net>

[#22285] Re: YASNP (Yet Another Selector Namespace Proposal) — Florian Gilcher <flo@...> 2009/02/20

[#22295] Re: YASNP (Yet Another Selector Namespace Proposal) — Yehuda Katz <wycats@...> 2009/02/20

Ok, based on a bunch of comments I got from Aaron Patterson and John

[#22316] Re: YASNP (Yet Another Selector Namespace Proposal) — Jim Weirich <jim.weirich@...> 2009/02/21

On Feb 20, 2009, at 8:39 AM, Yehuda Katz wrote:

[#22322] Re: YASNP (Yet Another Selector Namespace Proposal) — Aaron Patterson <aaron@...> 2009/02/22

On Sun, Feb 22, 2009 at 04:34:18AM +0900, Jim Weirich wrote:

[#22330] Re: YASNP (Yet Another Selector Namespace Proposal) — Eero Saynatkari <ruby-ml@...> 2009/02/22

Excerpts from Aaron Patterson's message of Sun Feb 22 04:35:41 +0200 2009:

[#22409] Re: YASNP (Yet Another Selector Namespace Proposal) — Yukihiro Matsumoto <matz@...> 2009/02/24

Hi,

[#22427] Re: YASNP (Yet Another Selector Namespace Proposal) — Brian Ford <brixen@...> 2009/02/24

On Feb 24, 2:07=A0am, Yukihiro Matsumoto <m...@ruby-lang.org> wrote:

[#22433] Re: YASNP (Yet Another Selector Namespace Proposal) — Eero Saynatkari <ruby-ml@...> 2009/02/24

Excerpts from brixen's message of Wed Feb 25 00:04:34 +0200 2009:

[#22435] Re: YASNP (Yet Another Selector Namespace Proposal) — Yehuda Katz <wycats@...> 2009/02/24

2009/2/24 Eero Saynatkari <ruby-ml@kittensoft.org>

[#22441] Re: YASNP (Yet Another Selector Namespace Proposal) — Brian Ford <brixen@...> 2009/02/25

On Feb 24, 3:17=A0pm, Yehuda Katz <wyc...@gmail.com> wrote:

[#22442] Re: YASNP (Yet Another Selector Namespace Proposal) — Yehuda Katz <wycats@...> 2009/02/25

2009/2/24 Brian Ford <brixen@gmail.com>

[#22446] Re: YASNP (Yet Another Selector Namespace Proposal) — Jim Deville <jdeville@...> 2009/02/25

I agree that this will be used in ways other than just framework creators. =

[#22448] Re: YASNP (Yet Another Selector Namespace Proposal) — Jim Weirich <jim.weirich@...> 2009/02/25

[#22449] Re: YASNP (Yet Another Selector Namespace Proposal) — Jim Deville <jdeville@...> 2009/02/25

[#22450] Re: YASNP (Yet Another Selector Namespace Proposal) — Yehuda Katz <wycats@...> 2009/02/25

I'm also in favor of discussing this, but all I hear so far in opposition is

[#22460] Re: YASNP (Yet Another Selector Namespace Proposal) — Florian Gilcher <flo@...> 2009/02/25

[#22471] Re: YASNP (Yet Another Selector Namespace Proposal) — Brian Ford <brixen@...> 2009/02/25

On Feb 24, 9:17=A0pm, Yehuda Katz <wyc...@gmail.com> wrote:

[#22490] Re: YASNP (Yet Another Selector Namespace Proposal) — Ola Bini <ola.bini@...> 2009/02/25

Yehuda Katz wrote:

[#22495] Re: YASNP (Yet Another Selector Namespace Proposal) — Yukihiro Matsumoto <matz@...> 2009/02/25

Hi,

[#22506] Re: YASNP (Yet Another Selector Namespace Proposal) — Ola Bini <ola.bini@...> 2009/02/25

Yukihiro Matsumoto wrote:

[#22510] Re: YASNP (Yet Another Selector Namespace Proposal) — Charles Oliver Nutter <charles.nutter@...> 2009/02/25

Ola Bini wrote:

[#22514] Re: YASNP (Yet Another Selector Namespace Proposal) — Ola Bini <ola.bini@...> 2009/02/25

Charles Oliver Nutter wrote:

[#22521] Re: YASNP (Yet Another Selector Namespace Proposal) — Charles Oliver Nutter <charles.nutter@...> 2009/02/25

Ola Bini wrote:

[#22522] Re: YASNP (Yet Another Selector Namespace Proposal) — Gary Wright <gwtmp01@...> 2009/02/25

[#22523] Re: YASNP (Yet Another Selector Namespace Proposal) — Yehuda Katz <wycats@...> 2009/02/25

2009/2/25 Gary Wright <gwtmp01@mac.com>

[#22501] Re: YASNP (Yet Another Selector Namespace Proposal) — Jim Weirich <jim.weirich@...> 2009/02/25

[#22325] suggestions for float — Roger Pack <rogerdpack@...>

Floating point rounding errors are common and "annoying"

20 messages 2009/02/22
[#22595] Re: suggestions for float — Roger Pack <rogerdpack@...> 2009/02/28

On Sat, Feb 21, 2009 at 11:59 PM, Roger Pack <rogerdpack@gmail.com> wrote:

[#22621] Re: suggestions for float — Yukihiro Matsumoto <matz@...> 2009/03/02

Hi,

[#22624] Re: suggestions for float — Eero Saynatkari <ruby-ml@...> 2009/03/02

Excerpts from Yukihiro Matsumoto's message of Mon Mar 02 12:46:27 +0200 2009:

[#22629] Re: suggestions for float — Kurt Stephens <kurt@...> 2009/03/02
[#22631] Re: suggestions for float — Eero Saynatkari <ruby-ml@...> 2009/03/02

Excerpts from Kurt Stephens's message of Mon Mar 02 20:27:09 +0200 2009:

[#22336] Floats are freezeable and taintable? — Charles Oliver Nutter <charles.nutter@...>

In adding an optimization for Float I realized that Float objects are

13 messages 2009/02/22

[#22353] [Bug #1195] String#% does not include prefix before zero value for # versions of numeric formats — Charles Nutter <redmine@...>

Bug #1195: String#% does not include prefix before zero value for # versions of numeric formats

10 messages 2009/02/23
[#22397] Re: [Bug #1195] String#% does not include prefix before zero value for # versions of numeric formats — Tanaka Akira <akr@...> 2009/02/24

In article <49a25ec0ce233_84c7e8c1f8909a@redmine.ruby-lang.org>,

[#22543] [Feature #1218] New method needed to set and get the current recursion limit — Conrad Taylor <redmine@...>

Feature #1218: New method needed to set and get the current recursion limit

12 messages 2009/02/26

[#22584] MBARI8 patch fixes bugs caused by incorrect volatile variable declarations — Brent Roman <brent@...>

16 messages 2009/02/28
[#22587] Re: MBARI8 patch fixes bugs caused by incorrect volatile variable declarations — Nobuyoshi Nakada <nobu@...> 2009/02/28

Hi,

[#22590] Re: MBARI8 patch fixes bugs caused by incorrect volatile variable declarations — Tanaka Akira <akr@...> 2009/02/28

In article <49a9024b.0e0d6e0a.11f5.ffffee2f@mx.google.com>,

[#22599] Re: MBARI8 patch fixes bugs caused by incorrect volatile variable declarations — Brent Roman <brent@...> 2009/02/28

[#22667] Re: MBARI8 patch fixes bugs caused by incorrect volatile variable declarations — Michael King <kingmt@...> 2009/03/04

I am having an issue with the MBARI patches. In our app the test suite has a

[ruby-core:22455] Re: YASNP (Yet Another Selector Namespace Proposal)

From: Charles Oliver Nutter <charles.nutter@...>
Date: 2009-02-25 07:30:24 UTC
List: ruby-core #22455
Yehuda Katz wrote:
> I'd like that a lot :)

Here's a patch that extends it at least to all forms of CallNode, which 
is probably the primary case. fcalls and vcalls are against self, and 
will probably be less common to namespace. attr/op/element assignments 
will probably be rare for similar reasons. But they'd probably all need 
similar treatment.

This patch is a bit bigger and messier, but still only about a half 
hour's work. A better design would be to enlist the parser in this 
process. It would also produce better-performing code; I don't expect 
this version to perform particularly well.

I've also attached a really primitive rspec that shows "using" inside an 
eval. In the current prototype, using is scoped to the eval body as if 
it were a file. I kinda like it.

- Charlie

Attachments (2)

more_selector_namespaces_2.patch (71.4 KB, text/x-diff)
diff --git a/src/org/jruby/ast/BlockAcceptingNode.java b/src/org/jruby/ast/BlockAcceptingNode.java
index a564863..b3c7535 100644
--- a/src/org/jruby/ast/BlockAcceptingNode.java
+++ b/src/org/jruby/ast/BlockAcceptingNode.java
@@ -29,6 +29,8 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import org.jruby.parser.ParserSupport;
+
 /**
  *  Any thing which implements this represents a Callable-like node which can have a block 
  *  associated with it as part of that call.  The calls which can be this are: CallNode, FCallNode,
@@ -41,5 +43,5 @@ package org.jruby.ast;
 public interface BlockAcceptingNode {
     public Node getIterNode();
     
-    public Node setIterNode(Node iterNode);
+    public Node setIterNode(Node iterNode, ParserSupport support);
 }
\ No newline at end of file
diff --git a/src/org/jruby/ast/CallManyArgsBlockNode.java b/src/org/jruby/ast/CallManyArgsBlockNode.java
index fa3f542..46c85f0 100644
--- a/src/org/jruby/ast/CallManyArgsBlockNode.java
+++ b/src/org/jruby/ast/CallManyArgsBlockNode.java
@@ -32,9 +32,11 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
 import org.jruby.RubyLocalJumpError.Reason;
 import org.jruby.exceptions.JumpException;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -46,15 +48,29 @@ import org.jruby.runtime.builtin.IRubyObject;
  */
 public final class CallManyArgsBlockNode extends CallNode {
     public CallManyArgsBlockNode(ISourcePosition position, Node receiverNode, String name, Node args, IterNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
     }
-        
+
+    public CallManyArgsBlockNode(ISourcePosition position, Node receiverNode, String name, Node args, IterNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
         IRubyObject[] args = ((ArrayNode) getArgsNode()).interpretPrimitive(runtime, context, self, aBlock);
         Block block = RuntimeHelpers.getBlock(context, self, iterNode);
-        
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            try {
+                return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, args, block);
+            } catch (JumpException.RetryJump rj) {
+                throw runtime.newLocalJumpError(Reason.RETRY, self, "retry is not supported outside rescue");
+            } finally {
+                block.escape();
+            }
+        }
         try {
             return callAdapter.call(context, self, receiver, args, block);
         } catch (JumpException.RetryJump rj) {
diff --git a/src/org/jruby/ast/CallManyArgsBlockPassNode.java b/src/org/jruby/ast/CallManyArgsBlockPassNode.java
index eba32f7..9afd267 100644
--- a/src/org/jruby/ast/CallManyArgsBlockPassNode.java
+++ b/src/org/jruby/ast/CallManyArgsBlockPassNode.java
@@ -32,7 +32,9 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -45,15 +47,24 @@ import org.jruby.runtime.builtin.IRubyObject;
 public final class CallManyArgsBlockPassNode extends CallNode {
     // For 'b.foo()'.  Args are only significant in maintaining backwards compatible AST structure
     public CallManyArgsBlockPassNode(ISourcePosition position, Node receiverNode, String name, Node args, BlockPassNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
     }
-        
+
+    // For 'b.foo()'.  Args are only significant in maintaining backwards compatible AST structure
+    public CallManyArgsBlockPassNode(ISourcePosition position, Node receiverNode, String name, Node args, BlockPassNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
         IRubyObject[] args = ((ArrayNode) getArgsNode()).interpretPrimitive(runtime, context, self, aBlock);
         Block block = RuntimeHelpers.getBlock(runtime, context, self, iterNode, aBlock);
-        
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, args, block);
+        }
         return callAdapter.call(context, self, receiver, args, block);
     }
 }
diff --git a/src/org/jruby/ast/CallManyArgsNode.java b/src/org/jruby/ast/CallManyArgsNode.java
index 2775fb5..4e6ee45 100644
--- a/src/org/jruby/ast/CallManyArgsNode.java
+++ b/src/org/jruby/ast/CallManyArgsNode.java
@@ -32,8 +32,11 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -43,11 +46,15 @@ import org.jruby.runtime.builtin.IRubyObject;
  */
 public final class CallManyArgsNode extends CallNode {    
     public CallManyArgsNode(ISourcePosition position, Node receiverNode, String name, Node args) {
-        super(position, receiverNode, name, args, null);
+        super(position, receiverNode, name, args, null, null);
     }
-     
+
+    public CallManyArgsNode(ISourcePosition position, Node receiverNode, String name, Node args, List<Node> namespaces) {
+        super(position, receiverNode, name, args, null, namespaces);
+    }
+
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new CallManyArgsBlockNode(getPosition(), getReceiverNode(), getName(), getArgsNode(), (IterNode) iterNode);
     }
     
@@ -55,7 +62,11 @@ public final class CallManyArgsNode extends CallNode {
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
         IRubyObject[] args = ((ArrayNode) getArgsNode()).interpretPrimitive(runtime, context, self, aBlock);
-        
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, args);
+        }
         return callAdapter.call(context, self, receiver, args);
     }
 }
diff --git a/src/org/jruby/ast/CallNoArgBlockNode.java b/src/org/jruby/ast/CallNoArgBlockNode.java
index a7c8ae8..f2b3d6d 100644
--- a/src/org/jruby/ast/CallNoArgBlockNode.java
+++ b/src/org/jruby/ast/CallNoArgBlockNode.java
@@ -32,9 +32,11 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
 import org.jruby.RubyLocalJumpError.Reason;
 import org.jruby.exceptions.JumpException;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -47,19 +49,39 @@ import org.jruby.runtime.builtin.IRubyObject;
 public final class CallNoArgBlockNode extends CallNode {
     // For b.foo
     public CallNoArgBlockNode(ISourcePosition position, Node receiverNode, String name, IterNode iter) {
-        super(position, receiverNode, name, null, iter);
+        super(position, receiverNode, name, null, iter, null);
     }
 
     // For 'b.foo()'.  Args are only significant in maintaining backwards compatible AST structure
     public CallNoArgBlockNode(ISourcePosition position, Node receiverNode, String name, Node args, IterNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
     }
-        
+
+    // For b.foo
+    public CallNoArgBlockNode(ISourcePosition position, Node receiverNode, String name, IterNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, null, iter, namespaces);
+    }
+
+    // For 'b.foo()'.  Args are only significant in maintaining backwards compatible AST structure
+    public CallNoArgBlockNode(ISourcePosition position, Node receiverNode, String name, Node args, IterNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
         Block block = RuntimeHelpers.getBlock(context, self, iterNode);
-            
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            try {
+                return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, block);
+            } catch (JumpException.RetryJump rj) {
+                throw runtime.newLocalJumpError(Reason.RETRY, self, "retry is not supported outside rescue");
+            } finally {
+                block.escape();
+            }
+        }
         try {
             return callAdapter.call(context, self, receiver, block);
         } catch (JumpException.RetryJump rj) {
diff --git a/src/org/jruby/ast/CallNoArgBlockPassNode.java b/src/org/jruby/ast/CallNoArgBlockPassNode.java
index 229e5aa..226a191 100644
--- a/src/org/jruby/ast/CallNoArgBlockPassNode.java
+++ b/src/org/jruby/ast/CallNoArgBlockPassNode.java
@@ -32,7 +32,9 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -45,13 +47,23 @@ import org.jruby.runtime.builtin.IRubyObject;
 public final class CallNoArgBlockPassNode extends CallNode {
     // For 'b.foo()'.  Args are only significant in maintaining backwards compatible AST structure
     public CallNoArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, Node args, BlockPassNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
     }
-        
+
+    // For 'b.foo()'.  Args are only significant in maintaining backwards compatible AST structure
+    public CallNoArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, Node args, BlockPassNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
+        IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, RuntimeHelpers.getBlock(runtime, context, self, iterNode, aBlock));
+        }
         return callAdapter.call(context, self,
-                getReceiverNode().interpret(runtime, context, self, aBlock),
+                receiver,
                 RuntimeHelpers.getBlock(runtime, context, self, iterNode, aBlock));
     }
 }
diff --git a/src/org/jruby/ast/CallNoArgNode.java b/src/org/jruby/ast/CallNoArgNode.java
index 1b2cd40..faa09e6 100644
--- a/src/org/jruby/ast/CallNoArgNode.java
+++ b/src/org/jruby/ast/CallNoArgNode.java
@@ -32,11 +32,13 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
 import org.jruby.RubyClass;
 import org.jruby.exceptions.JumpException;
 import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.Visibility;
@@ -48,22 +50,39 @@ import org.jruby.runtime.builtin.IRubyObject;
 public final class CallNoArgNode extends CallNode {
     // For 'b.foo'
     public CallNoArgNode(ISourcePosition position, Node receiverNode, String name) {
-        super(position, receiverNode, name, null, null);
+        super(position, receiverNode, name, null, null, null);
+    }
+
+    // For 'b.foo()'.  Args are only significant in maintaining backwards compatible AST structure
+    public CallNoArgNode(ISourcePosition position, Node receiverNode, String name, List<Node> namespaces) {
+        super(position, receiverNode, name, null, null, namespaces);
     }
     
     // For 'b.foo()'.  Args are only significant in maintaining backwards compatible AST structure
     public CallNoArgNode(ISourcePosition position, Node receiverNode, Node args, String name) {
-        super(position, receiverNode, name, args, null);
+        super(position, receiverNode, name, args, null, null);
+    }
+
+    // For 'b.foo()'.  Args are only significant in maintaining backwards compatible AST structure
+    public CallNoArgNode(ISourcePosition position, Node receiverNode, Node args, String name, List<Node> namespaces) {
+        super(position, receiverNode, name, args, null, namespaces);
     }
     
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
-        return callAdapter.call(context, self, getReceiverNode().interpret(runtime, context, self, aBlock));
+        IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName);
+        }
+        return callAdapter.call(context, self, receiver);
     }
     
-    @Override
-    public Node setIterNode(Node iterNode) {
-        return new CallNoArgBlockNode(getPosition(), getReceiverNode(), getName(), getArgsNode(), (IterNode) iterNode);
+    public Node setIterNode(Node iterNode, ParserSupport support) {
+        if (support.getNamespaces().size() == 0) {
+            return new CallNoArgBlockNode(getPosition(), getReceiverNode(), getName(), getArgsNode(), (IterNode) iterNode);
+        }
+        return new CallNoArgBlockNode(getPosition(), getReceiverNode(), getName(), getArgsNode(), (IterNode) iterNode, namespaces);
     }
     
     @Override
diff --git a/src/org/jruby/ast/CallNode.java b/src/org/jruby/ast/CallNode.java
index 9111b99..856dac5 100644
--- a/src/org/jruby/ast/CallNode.java
+++ b/src/org/jruby/ast/CallNode.java
@@ -37,6 +37,8 @@ import java.util.List;
 import org.jruby.Ruby;
 import org.jruby.RubyArray;
 import org.jruby.RubyClass;
+import org.jruby.RubyHash;
+import org.jruby.RubyModule;
 import org.jruby.ast.types.INameNode;
 import org.jruby.ast.visitor.NodeVisitor;
 import org.jruby.evaluator.ASTInterpreter;
@@ -44,6 +46,7 @@ import org.jruby.exceptions.JumpException;
 import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.CallSite;
 import org.jruby.runtime.CallType;
@@ -60,14 +63,15 @@ public class CallNode extends Node implements INameNode, IArgumentNode, BlockAcc
     private Node argsNode;
     protected Node iterNode;
     public CallSite callAdapter;
+    protected List<Node> namespaces;
 
     @Deprecated
     public CallNode(ISourcePosition position, Node receiverNode, String name, Node argsNode) {
-        this(position, receiverNode, name, argsNode, null);
+        this(position, receiverNode, name, argsNode, null, null);
     }
     
     public CallNode(ISourcePosition position, Node receiverNode, String name, Node argsNode, 
-            Node iterNode) {
+            Node iterNode, List<Node> namespaces) {
         super(position);
         
         assert receiverNode != null : "receiverNode is not null";
@@ -76,6 +80,23 @@ public class CallNode extends Node implements INameNode, IArgumentNode, BlockAcc
         setArgsNode(argsNode);
         this.iterNode = iterNode;
         this.callAdapter = MethodIndex.getCallSite(name);
+        this.namespaces = namespaces;
+    }
+
+    protected DynamicMethod getNamespacedMethod(Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject receiver, Block aBlock) {
+        DynamicMethod method = null;
+        if (namespaces != null) {
+            for (Node node : namespaces) {
+                IRubyObject namespace = ((RubyArray)node.interpret(runtime, context, self, aBlock)).eltInternal(0);
+                RubyModule nsModule = ((RubyModule)((RubyHash)namespace).keys().eltInternal(0));
+                RubyClass targetClass = (RubyClass)((RubyHash)namespace).rb_values().eltInternal(0);
+                if (targetClass == receiver.getMetaClass()) {
+                    method = nsModule.searchMethod(callAdapter.methodName);
+                    if (method != null && !method.isUndefined()) break;
+                }
+            }
+        }
+        return method;
     }
 
     public NodeType getNodeType() {
@@ -94,7 +115,7 @@ public class CallNode extends Node implements INameNode, IArgumentNode, BlockAcc
         return iterNode;
     }
     
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         this.iterNode = iterNode;
         // refresh call adapter, since it matters if this is iter-based or not
         callAdapter = MethodIndex.getCallSite(callAdapter.methodName);
diff --git a/src/org/jruby/ast/CallOneArgBlockNode.java b/src/org/jruby/ast/CallOneArgBlockNode.java
index cc419de..69a2d52 100644
--- a/src/org/jruby/ast/CallOneArgBlockNode.java
+++ b/src/org/jruby/ast/CallOneArgBlockNode.java
@@ -32,7 +32,9 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -46,17 +48,31 @@ public final class CallOneArgBlockNode extends CallNode {
     private Node arg1;
     
     public CallOneArgBlockNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, IterNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
         
         assert args.size() == 1 : "args.size() is 1";
         
         arg1 = args.get(0);        
     }
-        
+
+    public CallOneArgBlockNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, IterNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+
+        assert args.size() == 1 : "args.size() is 1";
+
+        arg1 = args.get(0);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
-            
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName,
+                    arg1.interpret(runtime, context, self, aBlock),
+                    RuntimeHelpers.getBlock(context, self, iterNode));
+        }
         return callAdapter.call(context, self, receiver,
                 arg1.interpret(runtime, context, self, aBlock),
                 RuntimeHelpers.getBlock(context, self, iterNode));
diff --git a/src/org/jruby/ast/CallOneArgBlockPassNode.java b/src/org/jruby/ast/CallOneArgBlockPassNode.java
index 1488e64..c360748 100644
--- a/src/org/jruby/ast/CallOneArgBlockPassNode.java
+++ b/src/org/jruby/ast/CallOneArgBlockPassNode.java
@@ -32,7 +32,9 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -46,17 +48,29 @@ public final class CallOneArgBlockPassNode extends CallNode {
     private Node arg1;
     
     public CallOneArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, BlockPassNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
         
         assert args.size() == 1 : "args.size() is 1";
         
         arg1 = args.get(0);        
     }
-        
+
+    public CallOneArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, BlockPassNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+
+        assert args.size() == 1 : "args.size() is 1";
+
+        arg1 = args.get(0);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
-            
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, arg1.interpret(runtime, context, self, aBlock), RuntimeHelpers.getBlock(runtime, context, self, iterNode, aBlock));
+        }
         return callAdapter.call(context, self, receiver,
                 arg1.interpret(runtime, context, self, aBlock),
                 RuntimeHelpers.getBlock(runtime, context, self, iterNode, aBlock));
diff --git a/src/org/jruby/ast/CallOneArgNode.java b/src/org/jruby/ast/CallOneArgNode.java
index 4b15628..2538b5a 100644
--- a/src/org/jruby/ast/CallOneArgNode.java
+++ b/src/org/jruby/ast/CallOneArgNode.java
@@ -32,8 +32,11 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -45,21 +48,35 @@ public final class CallOneArgNode extends CallNode {
     private Node arg1;    
     
     public CallOneArgNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args) {
-        super(position, receiverNode, name, args, null);
+        super(position, receiverNode, name, args, null, null);
         
         assert args.size() == 1 : "args.size() is 1";
         
         arg1 = args.get(0);
     }
-    
+
+    public CallOneArgNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, List<Node> namespaces) {
+        super(position, receiverNode, name, args, null, namespaces);
+
+        assert args.size() == 1 : "args.size() is 1";
+
+        arg1 = args.get(0);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
-        return callAdapter.call(context, self, getReceiverNode().interpret(runtime, context, self, aBlock),
+        IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName,
+                    arg1.interpret(runtime, context, self, aBlock));
+        }
+        return callAdapter.call(context, self, receiver,
                 arg1.interpret(runtime, context, self, aBlock));
     }
     
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new CallOneArgBlockNode(getPosition(), getReceiverNode(), getName(), (ArrayNode) getArgsNode(), (IterNode) iterNode);
     }
 }
diff --git a/src/org/jruby/ast/CallSpecialArgBlockNode.java b/src/org/jruby/ast/CallSpecialArgBlockNode.java
index fc10179..2a3d73f 100644
--- a/src/org/jruby/ast/CallSpecialArgBlockNode.java
+++ b/src/org/jruby/ast/CallSpecialArgBlockNode.java
@@ -32,8 +32,10 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
 import org.jruby.RubyArray;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -45,15 +47,40 @@ import org.jruby.runtime.builtin.IRubyObject;
  */
 public final class CallSpecialArgBlockNode extends CallNode {
     public CallSpecialArgBlockNode(ISourcePosition position, Node receiverNode, String name, Node args, IterNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
     }
-        
+
+    public CallSpecialArgBlockNode(ISourcePosition position, Node receiverNode, String name, Node args, IterNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
         IRubyObject arg = getArgsNode().interpret(runtime, context, self, aBlock);
         Block block = RuntimeHelpers.getBlock(context, self, iterNode);
 
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            if (arg instanceof RubyArray) {
+                RubyArray nodes = (RubyArray) arg;
+
+                switch (nodes.size()) {
+                    case 0:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, block);
+                    case 1:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, nodes.eltInternal(0), block);
+                    case 2:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, nodes.eltInternal(0), nodes.eltInternal(1), block);
+                    case 3:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, nodes.eltInternal(0), nodes.eltInternal(1), nodes.eltInternal(2), block);
+                    default:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, nodes.toJavaArrayMaybeUnsafe(), block);
+                }
+            }
+
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, arg, block);
+        }
         if (arg instanceof RubyArray) {
             RubyArray nodes = (RubyArray) arg;
 
diff --git a/src/org/jruby/ast/CallSpecialArgBlockPassNode.java b/src/org/jruby/ast/CallSpecialArgBlockPassNode.java
index 1548ca0..00723b8 100644
--- a/src/org/jruby/ast/CallSpecialArgBlockPassNode.java
+++ b/src/org/jruby/ast/CallSpecialArgBlockPassNode.java
@@ -32,8 +32,10 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
 import org.jruby.RubyArray;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -45,15 +47,29 @@ import org.jruby.runtime.builtin.IRubyObject;
  */
 public final class CallSpecialArgBlockPassNode extends CallNode {
     public CallSpecialArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, Node args, BlockPassNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
     }
-        
+
+    public CallSpecialArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, Node args, BlockPassNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
         IRubyObject arg = getArgsNode().interpret(runtime, context, self, aBlock);
         Block block = RuntimeHelpers.getBlock(runtime, context, self, iterNode, aBlock);
 
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            if (arg instanceof RubyArray) {
+                RubyArray nodes = (RubyArray) arg;
+                return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, nodes.toJavaArrayMaybeUnsafe(), block);
+            } else {
+                return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, arg, block);
+            }
+        }
+
         if (arg instanceof RubyArray) {
             RubyArray nodes = (RubyArray) arg;
 
diff --git a/src/org/jruby/ast/CallSpecialArgNode.java b/src/org/jruby/ast/CallSpecialArgNode.java
index 8e9833c..bbda4db 100644
--- a/src/org/jruby/ast/CallSpecialArgNode.java
+++ b/src/org/jruby/ast/CallSpecialArgNode.java
@@ -32,9 +32,12 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
 import org.jruby.RubyArray;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -44,11 +47,15 @@ import org.jruby.runtime.builtin.IRubyObject;
  */
 public final class CallSpecialArgNode extends CallNode {
     public CallSpecialArgNode(ISourcePosition position, Node receiverNode, String name, Node args) {
-        super(position, receiverNode, name, args, null);
+        super(position, receiverNode, name, args, null, null);
     }
-    
+
+    public CallSpecialArgNode(ISourcePosition position, Node receiverNode, String name, Node args, List<Node> namespaces) {
+        super(position, receiverNode, name, args, null, namespaces);
+    }
+
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new CallSpecialArgBlockNode(getPosition(), getReceiverNode(), getName(), getArgsNode(), (IterNode) iterNode);
     }    
     
@@ -56,10 +63,31 @@ public final class CallSpecialArgNode extends CallNode {
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
         IRubyObject arg = getArgsNode().interpret(runtime, context, self, aBlock);
-        
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            if (arg instanceof RubyArray) {
+                RubyArray nodes = (RubyArray) arg;
+
+                switch (nodes.size()) {
+                    case 0:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName);
+                    case 1:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, nodes.eltInternal(0));
+                    case 2:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, nodes.eltInternal(0), nodes.eltInternal(1));
+                    case 3:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, nodes.eltInternal(0), nodes.eltInternal(1), nodes.eltInternal(2));
+                    default:
+                        return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, nodes.toJavaArrayMaybeUnsafe());
+                }
+            }
+
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName, arg);
+        }
         if (arg instanceof RubyArray) {
             RubyArray nodes = (RubyArray) arg;
-            
+
             switch (nodes.size()) {
                 case 0:
                     return callAdapter.call(context, self, receiver);
@@ -73,7 +101,7 @@ public final class CallSpecialArgNode extends CallNode {
                     return callAdapter.call(context, self, receiver, nodes.toJavaArrayMaybeUnsafe());
             }
         }
-        
+
         return callAdapter.call(context, self, receiver, arg);
     }
 }
diff --git a/src/org/jruby/ast/CallThreeArgBlockNode.java b/src/org/jruby/ast/CallThreeArgBlockNode.java
index 3df06ef..2591556 100644
--- a/src/org/jruby/ast/CallThreeArgBlockNode.java
+++ b/src/org/jruby/ast/CallThreeArgBlockNode.java
@@ -32,7 +32,9 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -48,7 +50,7 @@ public final class CallThreeArgBlockNode extends CallNode {
     private Node arg3;    
     
     public CallThreeArgBlockNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, IterNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
         
         assert args.size() == 3 : "args.size() is 3";
         
@@ -56,11 +58,29 @@ public final class CallThreeArgBlockNode extends CallNode {
         arg2 = args.get(1);
         arg3 = args.get(2);
     }
+
+    public CallThreeArgBlockNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, IterNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+
+        assert args.size() == 3 : "args.size() is 3";
+
+        arg1 = args.get(0);
+        arg2 = args.get(1);
+        arg3 = args.get(2);
+    }
         
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
-            
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName,
+                    arg1.interpret(runtime, context, self, aBlock),
+                    arg2.interpret(runtime, context, self, aBlock),
+                    arg3.interpret(runtime, context, self, aBlock),
+                    RuntimeHelpers.getBlock(context, self, iterNode));
+        }
         return callAdapter.callIter(context, self, receiver,
                 arg1.interpret(runtime, context, self, aBlock),
                 arg2.interpret(runtime, context, self, aBlock),
diff --git a/src/org/jruby/ast/CallThreeArgBlockPassNode.java b/src/org/jruby/ast/CallThreeArgBlockPassNode.java
index c603fe9..651a98a 100644
--- a/src/org/jruby/ast/CallThreeArgBlockPassNode.java
+++ b/src/org/jruby/ast/CallThreeArgBlockPassNode.java
@@ -32,7 +32,9 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -48,7 +50,7 @@ public final class CallThreeArgBlockPassNode extends CallNode {
     private Node arg3;    
     
     public CallThreeArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, BlockPassNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
         
         assert args.size() == 3 : "args.size() is 3";
         
@@ -56,11 +58,29 @@ public final class CallThreeArgBlockPassNode extends CallNode {
         arg2 = args.get(1);
         arg3 = args.get(2);
     }
-        
+
+    public CallThreeArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, BlockPassNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+
+        assert args.size() == 3 : "args.size() is 3";
+
+        arg1 = args.get(0);
+        arg2 = args.get(1);
+        arg3 = args.get(2);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
-            
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName,
+                    arg1.interpret(runtime, context, self, aBlock),
+                    arg2.interpret(runtime, context, self, aBlock),
+                    arg3.interpret(runtime, context, self, aBlock),
+                    RuntimeHelpers.getBlock(runtime, context, self, iterNode, aBlock));
+        }
         return callAdapter.call(context, self, receiver,
                 arg1.interpret(runtime, context, self, aBlock),
                 arg2.interpret(runtime, context, self, aBlock),
diff --git a/src/org/jruby/ast/CallThreeArgNode.java b/src/org/jruby/ast/CallThreeArgNode.java
index f55b916..a174065 100644
--- a/src/org/jruby/ast/CallThreeArgNode.java
+++ b/src/org/jruby/ast/CallThreeArgNode.java
@@ -32,8 +32,11 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -47,7 +50,7 @@ public final class CallThreeArgNode extends CallNode {
     private Node arg3;
     
     public CallThreeArgNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args) {
-        super(position, receiverNode, name, args, null);
+        super(position, receiverNode, name, args, null, null);
         
         assert args.size() == 3 : "args.size() is 3";
         
@@ -55,17 +58,36 @@ public final class CallThreeArgNode extends CallNode {
         arg2 = args.get(1);
         arg3 = args.get(2);        
     }
+
+    public CallThreeArgNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, List<Node> namespaces) {
+        super(position, receiverNode, name, args, null, namespaces);
+
+        assert args.size() == 3 : "args.size() is 3";
+
+        arg1 = args.get(0);
+        arg2 = args.get(1);
+        arg3 = args.get(2);
+    }
         
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
-        return callAdapter.call(context, self, getReceiverNode().interpret(runtime, context, self, aBlock),
+        IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName,
+                    arg1.interpret(runtime, context, self, aBlock),
+                    arg2.interpret(runtime, context, self, aBlock),
+                    arg3.interpret(runtime, context, self, aBlock));
+        }
+        return callAdapter.call(context, self, receiver,
                 arg1.interpret(runtime, context, self, aBlock),
                 arg2.interpret(runtime, context, self, aBlock),
                 arg3.interpret(runtime, context, self, aBlock));
     }
     
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new CallThreeArgBlockNode(getPosition(), getReceiverNode(), getName(), (ArrayNode) getArgsNode(), (IterNode) iterNode);
     }
 }
diff --git a/src/org/jruby/ast/CallTwoArgBlockNode.java b/src/org/jruby/ast/CallTwoArgBlockNode.java
index 5a28960..8d1293c 100644
--- a/src/org/jruby/ast/CallTwoArgBlockNode.java
+++ b/src/org/jruby/ast/CallTwoArgBlockNode.java
@@ -32,7 +32,9 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -47,20 +49,36 @@ public final class CallTwoArgBlockNode extends CallNode {
     private Node arg2;    
     
     public CallTwoArgBlockNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, IterNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
         
         assert args.size() == 2 : "args.size() is 2";
         
         arg1 = args.get(0);
         arg2 = args.get(1);
     }
+
+    public CallTwoArgBlockNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, IterNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+
+        assert args.size() == 2 : "args.size() is 2";
+
+        arg1 = args.get(0);
+        arg2 = args.get(1);
+    }
         
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
 
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName,
+                    arg1.interpret(runtime, context, self, aBlock),
+                    arg2.interpret(runtime, context, self, aBlock),
+                    RuntimeHelpers.getBlock(context, self, iterNode));
+        }
         return callAdapter.callIter(context, self, receiver,
-                arg1.interpret(runtime, context, self, aBlock), 
+                arg1.interpret(runtime, context, self, aBlock),
                 arg2.interpret(runtime, context, self, aBlock),
                 RuntimeHelpers.getBlock(context, self, iterNode));
     }
diff --git a/src/org/jruby/ast/CallTwoArgBlockPassNode.java b/src/org/jruby/ast/CallTwoArgBlockPassNode.java
index 366d5a9..778dca1 100644
--- a/src/org/jruby/ast/CallTwoArgBlockPassNode.java
+++ b/src/org/jruby/ast/CallTwoArgBlockPassNode.java
@@ -32,7 +32,9 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
 import org.jruby.runtime.Block;
@@ -47,20 +49,36 @@ public final class CallTwoArgBlockPassNode extends CallNode {
     private Node arg2;    
     
     public CallTwoArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, BlockPassNode iter) {
-        super(position, receiverNode, name, args, iter);
+        super(position, receiverNode, name, args, iter, null);
         
         assert args.size() == 2 : "args.size() is 2";
         
         arg1 = args.get(0);
         arg2 = args.get(1);
     }
-        
+
+    public CallTwoArgBlockPassNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, BlockPassNode iter, List<Node> namespaces) {
+        super(position, receiverNode, name, args, iter, namespaces);
+
+        assert args.size() == 2 : "args.size() is 2";
+
+        arg1 = args.get(0);
+        arg2 = args.get(1);
+    }
+
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
         IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
-            
+
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName,
+                    arg1.interpret(runtime, context, self, aBlock),
+                    arg2.interpret(runtime, context, self, aBlock),
+                    RuntimeHelpers.getBlock(runtime, context, self, iterNode, aBlock));
+        }
         return callAdapter.call(context, self, receiver,
-                arg1.interpret(runtime, context, self, aBlock), 
+                arg1.interpret(runtime, context, self, aBlock),
                 arg2.interpret(runtime, context, self, aBlock),
                 RuntimeHelpers.getBlock(runtime, context, self, iterNode, aBlock));
     }
diff --git a/src/org/jruby/ast/CallTwoArgNode.java b/src/org/jruby/ast/CallTwoArgNode.java
index 7128c9b..2116519 100644
--- a/src/org/jruby/ast/CallTwoArgNode.java
+++ b/src/org/jruby/ast/CallTwoArgNode.java
@@ -32,8 +32,11 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.ast;
 
+import java.util.List;
 import org.jruby.Ruby;
+import org.jruby.internal.runtime.methods.DynamicMethod;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -46,23 +49,39 @@ public final class CallTwoArgNode extends CallNode {
     private Node arg2;
     
     public CallTwoArgNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args) {
-        super(position, receiverNode, name, args, null);
+        super(position, receiverNode, name, args, null, null);
         
         assert args.size() == 2 : "args.size() is 2";
         
         arg1 = args.get(0);
         arg2 = args.get(1);
     }
+
+    public CallTwoArgNode(ISourcePosition position, Node receiverNode, String name, ArrayNode args, List<Node> namespaces) {
+        super(position, receiverNode, name, args, null, namespaces);
+
+        assert args.size() == 2 : "args.size() is 2";
+
+        arg1 = args.get(0);
+        arg2 = args.get(1);
+    }
         
     @Override
     public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
-        return callAdapter.call(context, self, getReceiverNode().interpret(runtime, context, self, aBlock),
+        IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
+        DynamicMethod method = getNamespacedMethod(runtime, context, self, receiver, aBlock);
+        if (method != null && !method.isUndefined()) {
+            return method.call(context, receiver, receiver.getMetaClass(), callAdapter.methodName,
+                    arg1.interpret(runtime, context, self, aBlock),
+                    arg2.interpret(runtime, context, self, aBlock));
+        }
+        return callAdapter.call(context, self, receiver,
                 arg1.interpret(runtime, context, self, aBlock),
                 arg2.interpret(runtime, context, self, aBlock));
     }
     
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new CallTwoArgBlockNode(getPosition(), getReceiverNode(), getName(), (ArrayNode) getArgsNode(), (IterNode) iterNode);
     }
 }
diff --git a/src/org/jruby/ast/FCallManyArgsNode.java b/src/org/jruby/ast/FCallManyArgsNode.java
index f83ee5f..8fdbe6d 100644
--- a/src/org/jruby/ast/FCallManyArgsNode.java
+++ b/src/org/jruby/ast/FCallManyArgsNode.java
@@ -35,6 +35,7 @@ package org.jruby.ast;
 import org.jruby.Ruby;
 import org.jruby.ast.types.INameNode;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -49,7 +50,7 @@ public class FCallManyArgsNode extends FCallNode implements INameNode, IArgument
     }
  
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new FCallManyArgsBlockNode(getPosition(), getName(), getArgsNode(), (IterNode) iterNode);
     }      
     
diff --git a/src/org/jruby/ast/FCallNoArgNode.java b/src/org/jruby/ast/FCallNoArgNode.java
index 76404df..cf8e559 100644
--- a/src/org/jruby/ast/FCallNoArgNode.java
+++ b/src/org/jruby/ast/FCallNoArgNode.java
@@ -7,6 +7,7 @@ package org.jruby.ast;
 
 import org.jruby.Ruby;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -32,7 +33,7 @@ public class FCallNoArgNode extends FCallNode {
     }
     
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new FCallNoArgBlockNode(getPosition(), getName(), getArgsNode(), (IterNode) iterNode);
     }
 }
diff --git a/src/org/jruby/ast/FCallNode.java b/src/org/jruby/ast/FCallNode.java
index 8c9752d..effa85c 100644
--- a/src/org/jruby/ast/FCallNode.java
+++ b/src/org/jruby/ast/FCallNode.java
@@ -38,6 +38,7 @@ import org.jruby.ast.types.INameNode;
 import org.jruby.ast.visitor.NodeVisitor;
 import org.jruby.evaluator.ASTInterpreter;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.CallSite;
 import org.jruby.runtime.MethodIndex;
@@ -83,7 +84,7 @@ public class FCallNode extends Node implements INameNode, IArgumentNode, BlockAc
         return iterNode;
     }
     
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         this.iterNode = iterNode;
         callAdapter = MethodIndex.getFunctionalCallSite(callAdapter.methodName);
         
diff --git a/src/org/jruby/ast/FCallOneArgNode.java b/src/org/jruby/ast/FCallOneArgNode.java
index 64d8bae..1321a60 100644
--- a/src/org/jruby/ast/FCallOneArgNode.java
+++ b/src/org/jruby/ast/FCallOneArgNode.java
@@ -7,6 +7,7 @@ package org.jruby.ast;
 
 import org.jruby.Ruby;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -27,7 +28,7 @@ public class FCallOneArgNode extends FCallNode {
     }
 
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new FCallOneArgBlockNode(getPosition(), getName(), (ArrayNode) getArgsNode(), (IterNode) iterNode);
     }
     
diff --git a/src/org/jruby/ast/FCallSpecialArgNode.java b/src/org/jruby/ast/FCallSpecialArgNode.java
index 29c8de7..d9af48d 100644
--- a/src/org/jruby/ast/FCallSpecialArgNode.java
+++ b/src/org/jruby/ast/FCallSpecialArgNode.java
@@ -8,6 +8,7 @@ package org.jruby.ast;
 import org.jruby.Ruby;
 import org.jruby.RubyArray;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -21,7 +22,7 @@ public class FCallSpecialArgNode extends FCallNode {
     }
 
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new FCallSpecialArgBlockNode(getPosition(), getName(), getArgsNode(), (IterNode) iterNode);
     }
     
diff --git a/src/org/jruby/ast/FCallThreeArgNode.java b/src/org/jruby/ast/FCallThreeArgNode.java
index e1b0f91..f15da38 100644
--- a/src/org/jruby/ast/FCallThreeArgNode.java
+++ b/src/org/jruby/ast/FCallThreeArgNode.java
@@ -7,6 +7,7 @@ package org.jruby.ast;
 
 import org.jruby.Ruby;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -31,7 +32,7 @@ public class FCallThreeArgNode extends FCallNode {
     }
 
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new FCallThreeArgBlockNode(getPosition(), getName(), (ArrayNode) getArgsNode(), (IterNode) iterNode);
     }
     
diff --git a/src/org/jruby/ast/FCallTwoArgNode.java b/src/org/jruby/ast/FCallTwoArgNode.java
index 4635dd2..5b38ef7 100644
--- a/src/org/jruby/ast/FCallTwoArgNode.java
+++ b/src/org/jruby/ast/FCallTwoArgNode.java
@@ -7,6 +7,7 @@ package org.jruby.ast;
 
 import org.jruby.Ruby;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -29,7 +30,7 @@ public class FCallTwoArgNode extends FCallNode {
     }
     
     @Override
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         return new FCallTwoArgBlockNode(getPosition(), getName(), (ArrayNode) getArgsNode(), (IterNode) iterNode);
     }
 
diff --git a/src/org/jruby/ast/SuperNode.java b/src/org/jruby/ast/SuperNode.java
index 44b270f..7026226 100644
--- a/src/org/jruby/ast/SuperNode.java
+++ b/src/org/jruby/ast/SuperNode.java
@@ -39,6 +39,7 @@ import org.jruby.ast.visitor.NodeVisitor;
 import org.jruby.evaluator.ASTInterpreter;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -88,7 +89,7 @@ public class SuperNode extends Node implements BlockAcceptingNode {
         return iterNode;
     }
 
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         this.iterNode = iterNode;
         
         return this;
diff --git a/src/org/jruby/ast/ZSuperNode.java b/src/org/jruby/ast/ZSuperNode.java
index b234039..37e7b9a 100644
--- a/src/org/jruby/ast/ZSuperNode.java
+++ b/src/org/jruby/ast/ZSuperNode.java
@@ -40,6 +40,7 @@ import org.jruby.ast.visitor.NodeVisitor;
 import org.jruby.evaluator.ASTInterpreter;
 import org.jruby.javasupport.util.RuntimeHelpers;
 import org.jruby.lexer.yacc.ISourcePosition;
+import org.jruby.parser.ParserSupport;
 import org.jruby.runtime.Arity;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
@@ -82,7 +83,7 @@ public class ZSuperNode extends Node implements IArityNode, BlockAcceptingNode {
         return iterNode;
     }
 
-    public Node setIterNode(Node iterNode) {
+    public Node setIterNode(Node iterNode, ParserSupport support) {
         this.iterNode = iterNode;
         
         return this;
diff --git a/src/org/jruby/parser/DefaultRubyParser.java b/src/org/jruby/parser/DefaultRubyParser.java
index 03d56c4..f0037b4 100644
--- a/src/org/jruby/parser/DefaultRubyParser.java
+++ b/src/org/jruby/parser/DefaultRubyParser.java
@@ -3423,7 +3423,7 @@ public Object case341_line1266(Object yyVal, Object[] yyVals, int yyTop) {
 	          if (((BlockAcceptingNode)yyVals[-1+yyTop]).getIterNode() instanceof BlockPassNode) {
                       throw new SyntaxException(PID.BLOCK_ARG_AND_BLOCK_GIVEN, getPosition(((Node)yyVals[-1+yyTop])), "Both block arg and actual block given.");
                   }
-		  yyVal = ((BlockAcceptingNode)yyVals[-1+yyTop]).setIterNode(((IterNode)yyVals[0+yyTop]));
+		  yyVal = ((BlockAcceptingNode)yyVals[-1+yyTop]).setIterNode(((IterNode)yyVals[0+yyTop]), support);
 		  ((Node)yyVal).setPosition(support.union(((Node)yyVals[-1+yyTop]), ((IterNode)yyVals[0+yyTop])));
     return yyVal;
 }
@@ -3603,7 +3603,7 @@ public Object case290_line1088(Object yyVal, Object[] yyVals, int yyTop) {
                       ((BlockAcceptingNode)yyVals[-1+yyTop]).getIterNode() instanceof BlockPassNode) {
                       throw new SyntaxException(PID.BLOCK_ARG_AND_BLOCK_GIVEN, getPosition(((Node)yyVals[-1+yyTop])), "Both block arg and actual block given.");
 		  }
-		  yyVal = ((BlockAcceptingNode)yyVals[-1+yyTop]).setIterNode(((IterNode)yyVals[0+yyTop]));
+		  yyVal = ((BlockAcceptingNode)yyVals[-1+yyTop]).setIterNode(((IterNode)yyVals[0+yyTop]), support);
 		  ((Node)yyVal).setPosition(support.union(((Node)yyVals[-1+yyTop]), ((IterNode)yyVals[0+yyTop])));
     return yyVal;
 }
diff --git a/src/org/jruby/parser/ParserSupport.java b/src/org/jruby/parser/ParserSupport.java
index f3d9b97..e497670 100644
--- a/src/org/jruby/parser/ParserSupport.java
+++ b/src/org/jruby/parser/ParserSupport.java
@@ -35,6 +35,8 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby.parser;
 
+import java.util.ArrayList;
+import java.util.List;
 import org.jruby.ast.AndNode;
 import org.jruby.ast.ArgsPreOneArgNode;
 import org.jruby.ast.ArgsPreTwoArgNode;
@@ -182,6 +184,8 @@ public class ParserSupport {
     private ParserConfiguration configuration;
     private RubyParserResult result;
 
+    private List namespaces = new ArrayList();
+
     public void reset() {
         inSingleton = 0;
         inDefinition = false;
@@ -192,6 +196,10 @@ public class ParserSupport {
             throw new SyntaxException(PID.DUBY_EXTENSIONS_OFF, position, "Duby extensions not configured");
         }
     }
+
+    public List getNamespaces() {
+        return namespaces;
+    }
     
     public StaticScope getCurrentScope() {
         return currentScope;
@@ -920,10 +928,16 @@ public class ParserSupport {
         ISourcePosition position = union(receiver, name);
         
         if (receiver == null) receiver = NilImplicitNode.NIL;
-        
-        if (iter != null) return new CallNoArgBlockNode(position, receiver, (String) name.getValue(), iter);
-        
-        return new CallNoArgNode(position, receiver, (String) name.getValue());
+
+        if (namespaces.size() > 0) {
+            if (iter != null) return new CallNoArgBlockNode(position, receiver, (String) name.getValue(), iter, namespaces);
+            
+            return new CallNoArgNode(position, receiver, (String) name.getValue(), namespaces);
+        } else {
+            if (iter != null) return new CallNoArgBlockNode(position, receiver, (String) name.getValue(), iter);
+            
+            return new CallNoArgNode(position, receiver, (String) name.getValue());
+        }
     }
     
     private Node new_call_complexargs(Node receiver, Token name, Node args, Node iter) {
@@ -936,9 +950,15 @@ public class ParserSupport {
             return new_call_blockpass(receiver, name, (BlockPassNode) args);
         }
 
-        if (iter != null) return new CallSpecialArgBlockNode(union(receiver, args), receiver,(String) name.getValue(), args, (IterNode) iter);
+        if (namespaces.size() == 0) {
+            if (iter != null) return new CallSpecialArgBlockNode(union(receiver, args), receiver,(String) name.getValue(), args, (IterNode) iter);
 
-        return new CallSpecialArgNode(union(receiver, args), receiver, (String) name.getValue(), args);
+            return new CallSpecialArgNode(union(receiver, args), receiver, (String) name.getValue(), args);
+        } else {
+            if (iter != null) return new CallSpecialArgBlockNode(union(receiver, args), receiver,(String) name.getValue(), args, (IterNode) iter, namespaces);
+
+            return new CallSpecialArgNode(union(receiver, args), receiver, (String) name.getValue(), args, namespaces);
+        }
     }
     
     private Node new_call_blockpass(Node receiver, Token operation, BlockPassNode blockPass) {
@@ -946,21 +966,39 @@ public class ParserSupport {
         String name = (String) operation.getValue();
         Node args = blockPass.getArgsNode();
         
-        if (args == null) return new CallNoArgBlockPassNode(position, receiver, name, args, blockPass);
-        if (!(args instanceof ArrayNode)) return new CallSpecialArgBlockPassNode(position, receiver, name, args, blockPass);
-        
-        switch (((ArrayNode) args).size()) {
-            case 0:  // foo()
-                return new CallNoArgBlockPassNode(position, receiver, name, args, blockPass);
-            case 1:
-                return new CallOneArgBlockPassNode(position, receiver, name, (ArrayNode) args, blockPass);
-            case 2:
-                return new CallTwoArgBlockPassNode(position, receiver, name, (ArrayNode) args, blockPass);
-            case 3:
-                return new CallThreeArgBlockPassNode(position, receiver, name, (ArrayNode) args, blockPass);
-            default:
-                return new CallManyArgsBlockPassNode(position, receiver, name, args, blockPass);
-        } 
+        if (namespaces.size() == 0) {
+            if (args == null) return new CallNoArgBlockPassNode(position, receiver, name, args, blockPass);
+            if (!(args instanceof ArrayNode)) return new CallSpecialArgBlockPassNode(position, receiver, name, args, blockPass);
+
+            switch (((ArrayNode) args).size()) {
+                case 0:  // foo()
+                    return new CallNoArgBlockPassNode(position, receiver, name, args, blockPass);
+                case 1:
+                    return new CallOneArgBlockPassNode(position, receiver, name, (ArrayNode) args, blockPass);
+                case 2:
+                    return new CallTwoArgBlockPassNode(position, receiver, name, (ArrayNode) args, blockPass);
+                case 3:
+                    return new CallThreeArgBlockPassNode(position, receiver, name, (ArrayNode) args, blockPass);
+                default:
+                    return new CallManyArgsBlockPassNode(position, receiver, name, args, blockPass);
+            }
+        } else {
+            if (args == null) return new CallNoArgBlockPassNode(position, receiver, name, args, blockPass, namespaces);
+            if (!(args instanceof ArrayNode)) return new CallSpecialArgBlockPassNode(position, receiver, name, args, blockPass, namespaces);
+
+            switch (((ArrayNode) args).size()) {
+                case 0:  // foo()
+                    return new CallNoArgBlockPassNode(position, receiver, name, args, blockPass, namespaces);
+                case 1:
+                    return new CallOneArgBlockPassNode(position, receiver, name, (ArrayNode) args, blockPass, namespaces);
+                case 2:
+                    return new CallTwoArgBlockPassNode(position, receiver, name, (ArrayNode) args, blockPass, namespaces);
+                case 3:
+                    return new CallThreeArgBlockPassNode(position, receiver, name, (ArrayNode) args, blockPass, namespaces);
+                default:
+                    return new CallManyArgsBlockPassNode(position, receiver, name, args, blockPass, namespaces);
+            }
+        }
     }
 
     public Node new_call(Node receiver, Token name, Node argsNode, Node iter) {
@@ -969,27 +1007,52 @@ public class ParserSupport {
         
         ArrayNode args = (ArrayNode) argsNode;
 
-        switch (args.size()) {
-            case 0:
-                if (iter != null) return new CallNoArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
-                    
-                return new CallNoArgNode(union(receiver, args), receiver, args, (String) name.getValue());
-            case 1:
-                if (iter != null) return new CallOneArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
-                
-                return new CallOneArgNode(union(receiver, args), receiver, (String) name.getValue(), args);
-            case 2:
-                if (iter != null) return new CallTwoArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
-                
-                return new CallTwoArgNode(union(receiver, args), receiver, (String) name.getValue(), args);
-            case 3:
-                if (iter != null) return new CallThreeArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
-                
-                return new CallThreeArgNode(union(receiver, args), receiver, (String) name.getValue(), args);
-            default:
-                if (iter != null) return new CallManyArgsBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
+        if (namespaces.size() == 0) {
+            switch (args.size()) {
+                case 0:
+                    if (iter != null) return new CallNoArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
+
+                    return new CallNoArgNode(union(receiver, args), receiver, args, (String) name.getValue());
+                case 1:
+                    if (iter != null) return new CallOneArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
+
+                    return new CallOneArgNode(union(receiver, args), receiver, (String) name.getValue(), args);
+                case 2:
+                    if (iter != null) return new CallTwoArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
+
+                    return new CallTwoArgNode(union(receiver, args), receiver, (String) name.getValue(), args);
+                case 3:
+                    if (iter != null) return new CallThreeArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
 
-                return new CallManyArgsNode(union(receiver, args), receiver, (String) name.getValue(), args);
+                    return new CallThreeArgNode(union(receiver, args), receiver, (String) name.getValue(), args);
+                default:
+                    if (iter != null) return new CallManyArgsBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter);
+
+                    return new CallManyArgsNode(union(receiver, args), receiver, (String) name.getValue(), args);
+            }
+        } else {
+            switch (args.size()) {
+                case 0:
+                    if (iter != null) return new CallNoArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter, namespaces);
+
+                    return new CallNoArgNode(union(receiver, args), receiver, args, (String) name.getValue(), namespaces);
+                case 1:
+                    if (iter != null) return new CallOneArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter, namespaces);
+
+                    return new CallOneArgNode(union(receiver, args), receiver, (String) name.getValue(), args, namespaces);
+                case 2:
+                    if (iter != null) return new CallTwoArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter, namespaces);
+
+                    return new CallTwoArgNode(union(receiver, args), receiver, (String) name.getValue(), args, namespaces);
+                case 3:
+                    if (iter != null) return new CallThreeArgBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter, namespaces);
+
+                    return new CallThreeArgNode(union(receiver, args), receiver, (String) name.getValue(), args, namespaces);
+                default:
+                    if (iter != null) return new CallManyArgsBlockNode(union(receiver, args), receiver, (String) name.getValue(), args, (IterNode) iter, namespaces);
+
+                    return new CallManyArgsNode(union(receiver, args), receiver, (String) name.getValue(), args, namespaces);
+            }
         }
     }
 
@@ -1014,6 +1077,14 @@ public class ParserSupport {
     
     private Node new_fcall_simpleargs(Token operation, ArrayNode args, Node iter) {
         String name = (String) operation.getValue();
+
+        // it if's a "using" call add a namespace and return a nil node
+        if (name.equals("using")) {
+            namespaces.add(args);
+            return new NilNode(union(operation, args));
+        }
+
+        // otherwise, if we have a namespace, pass it into the FCall
             
         switch (args.size()) {
             case 0:  // foo()
diff --git a/src/org/jruby/parser/Ruby19Parser.java b/src/org/jruby/parser/Ruby19Parser.java
index dd64f37..865473b 100644
--- a/src/org/jruby/parser/Ruby19Parser.java
+++ b/src/org/jruby/parser/Ruby19Parser.java
@@ -2730,7 +2730,7 @@ public Object case282_line1092(Object yyVal, Object[] yyVals, int yyTop) {
                           ((BlockAcceptingNode)yyVals[-1+yyTop]).getIterNode() instanceof BlockPassNode) {
                         throw new SyntaxException(PID.BLOCK_ARG_AND_BLOCK_GIVEN, getPosition(((Node)yyVals[-1+yyTop])), "Both block arg and actual block given.");
                     }
-                    yyVal = ((BlockAcceptingNode)yyVals[-1+yyTop]).setIterNode(((IterNode)yyVals[0+yyTop]));
+                    yyVal = ((BlockAcceptingNode)yyVals[-1+yyTop]).setIterNode(((IterNode)yyVals[0+yyTop]), support);
                     ((Node)yyVal).setPosition(support.union(((Node)yyVals[-1+yyTop]), ((IterNode)yyVals[0+yyTop])));
     return yyVal;
 }
@@ -3307,7 +3307,7 @@ public Object case372_line1401(Object yyVal, Object[] yyVals, int yyTop) {
                     if (((BlockAcceptingNode)yyVals[-1+yyTop]).getIterNode() instanceof BlockPassNode) {
                         throw new SyntaxException(PID.BLOCK_ARG_AND_BLOCK_GIVEN, getPosition(((Node)yyVals[-1+yyTop])), "Both block arg and actual block given.");
                     }
-                    yyVal = ((BlockAcceptingNode)yyVals[-1+yyTop]).setIterNode(((IterNode)yyVals[0+yyTop]));
+                    yyVal = ((BlockAcceptingNode)yyVals[-1+yyTop]).setIterNode(((IterNode)yyVals[0+yyTop]), support);
                     ((Node)yyVal).setPosition(support.union(((Node)yyVals[-1+yyTop]), ((IterNode)yyVals[0+yyTop])));
     return yyVal;
 }
namespace_spec.rb (598 Bytes, text/x-ruby)
module Namespace
  def to_s
    'my string'
  end

  def to_i(x)
    42
  end

  def each
    [1,2,3].each {|i| yield i}
  end
end

describe "A simple namespace" do
  it 'applies its methods only to designated classes' do
    c = Class.new
    c.class_eval "
      using Namespace => String
      def foo; 'hello'.to_s; end
      def bar; '50'.to_i(16); end
      def baz; i = 0; 'goodbye'.each {|j| i += j}; i; end
      def quux; 42.to_s; end
    "
    c_obj = c.new
    c_obj.foo.should == 'my string'
    c_obj.bar.should == 42
    c_obj.baz.should == 6
    c_obj.quux.should == '42'
  end
end

In This Thread