Beispiel #1
0
        public virtual Proc/*!*/ ToProc(RubyScope/*!*/ scope) {
            ContractUtils.RequiresNotNull(scope, "scope");

            if (_procDispatcher == null) {
                var site = CallSite<Func<CallSite, object, object, object>>.Create(
                    // TODO: use InvokeBinder
                    RubyCallAction.Make(
                        scope.RubyContext, "call",
                        new RubyCallSignature(1, RubyCallFlags.HasImplicitSelf | RubyCallFlags.HasSplattedArgument)
                    )
                );

                var block = new BlockCallTargetUnsplatN((blockParam, self, args, unsplat) => {
                    // block takes no parameters but unsplat => all actual arguments are added to unsplat:
                    Debug.Assert(args.Length == 0);

                    return site.Target(site, this, unsplat);
                });

                _procDispatcher = new BlockDispatcherUnsplatN(0, 
                    BlockDispatcher.MakeAttributes(BlockSignatureAttributes.HasUnsplatParameter, _info.GetArity()),
                    null, 0
                );

                _procDispatcher.SetMethod(block);
            }

            // TODO: 
            // MRI: source file/line are that of the to_proc method call:
            return new Proc(ProcKind.Block, scope.SelfObject, scope, _procDispatcher);
        }
Beispiel #2
0
        /// <summary>
        /// Creates a proc that invokes a method of given name.
        /// <code>
        /// Proc.new do |*args| 
        ///   raise ArgumentException if args.size == 0
        ///   obj.methodName(args.delete_at(0), args) 
        /// end
        /// </code>
        /// </summary>
        public static Proc/*!*/ CreateMethodInvoker(RubyScope/*!*/ scope, string/*!*/ methodName) {
            ContractUtils.RequiresNotNull(scope, "scope");

            var site = CallSite<Func<CallSite, object, object, object, object>>.Create(
                RubyCallAction.Make(
                    scope.RubyContext, methodName,
                    new RubyCallSignature(0, RubyCallFlags.HasScope | RubyCallFlags.HasSplattedArgument)
                )
            );

            var block = new BlockCallTargetUnsplatN((blockParam, self, args, unsplat) => {
                Debug.Assert(args.Length == 0);
                if (unsplat.Count == 0) {
                    throw RubyExceptions.CreateArgumentError("no receiver given");
                }
                object target = unsplat[0];
                unsplat.RemoveAt(0);
                return site.Target(site, scope, target, unsplat);
            });

            var procDispatcher = new BlockDispatcherUnsplatN(0,
                BlockDispatcher.MakeAttributes(BlockSignatureAttributes.HasUnsplatParameter, -1),
                null, 0
            );

            procDispatcher.SetMethod(block);
            return new Proc(ProcKind.Proc, scope.SelfObject, scope, procDispatcher);
        }