Source Code Cross Referenced for RubyObject.java in  » Scripting » jruby » org » jruby » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jruby » org.jruby 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /***** BEGIN LICENSE BLOCK *****
0002:         * Version: CPL 1.0/GPL 2.0/LGPL 2.1
0003:         *
0004:         * The contents of this file are subject to the Common Public
0005:         * License Version 1.0 (the "License"); you may not use this file
0006:         * except in compliance with the License. You may obtain a copy of
0007:         * the License at http://www.eclipse.org/legal/cpl-v10.html
0008:         *
0009:         * Software distributed under the License is distributed on an "AS
0010:         * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
0011:         * implied. See the License for the specific language governing
0012:         * rights and limitations under the License.
0013:         *
0014:         * Copyright (C) 2001 Chad Fowler <chadfowler@chadfowler.com>
0015:         * Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
0016:         * Copyright (C) 2001-2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
0017:         * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
0018:         * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
0019:         * Copyright (C) 2004-2006 Thomas E Enebo <enebo@acm.org>
0020:         * Copyright (C) 2004-2005 Charles O Nutter <headius@headius.com>
0021:         * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
0022:         * Copyright (C) 2006 Ola Bini <ola.bini@ki.se>
0023:         * Copyright (C) 2006 Miguel Covarrubias <mlcovarrubias@gmail.com>
0024:         * Copyright (C) 2007 MenTaLguY <mental@rydia.net>
0025:         * 
0026:         * Alternatively, the contents of this file may be used under the terms of
0027:         * either of the GNU General Public License Version 2 or later (the "GPL"),
0028:         * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
0029:         * in which case the provisions of the GPL or the LGPL are applicable instead
0030:         * of those above. If you wish to allow use of your version of this file only
0031:         * under the terms of either the GPL or the LGPL, and not to allow others to
0032:         * use your version of this file under the terms of the CPL, indicate your
0033:         * decision by deleting the provisions above and replace them with the notice
0034:         * and other provisions required by the GPL or the LGPL. If you do not delete
0035:         * the provisions above, a recipient may use your version of this file under
0036:         * the terms of any one of the CPL, the GPL or the LGPL.
0037:         ***** END LICENSE BLOCK *****/package org.jruby;
0038:
0039:        import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
0040:        import org.jruby.evaluator.EvaluationState;
0041:        import org.jruby.exceptions.JumpException;
0042:        import org.jruby.internal.runtime.methods.DynamicMethod;
0043:        import org.jruby.lexer.yacc.ISourcePosition;
0044:        import org.jruby.runtime.Arity;
0045:        import org.jruby.runtime.Block;
0046:        import org.jruby.runtime.CallType;
0047:        import org.jruby.runtime.CallbackFactory;
0048:        import org.jruby.runtime.ObjectAllocator;
0049:        import org.jruby.runtime.ThreadContext;
0050:        import org.jruby.runtime.Visibility;
0051:        import org.jruby.runtime.builtin.IRubyObject;
0052:        import org.jruby.runtime.callback.Callback;
0053:        import org.jruby.util.IdUtil;
0054:        import org.jruby.util.collections.SinglyLinkedList;
0055:        import java.util.ArrayList;
0056:        import java.util.Collections;
0057:        import java.util.HashMap;
0058:        import java.util.Iterator;
0059:        import java.util.List;
0060:        import java.util.Map;
0061:        import org.jruby.ast.Node;
0062:        import org.jruby.runtime.ClassIndex;
0063:        import org.jruby.runtime.MethodIndex;
0064:
0065:        /**
0066:         *
0067:         * @author  jpetersen
0068:         */
0069:        public class RubyObject implements  Cloneable, IRubyObject {
0070:
0071:            private RubyObject() {
0072:            };
0073:
0074:            // An instance that never equals any other instance
0075:            public static final IRubyObject NEVER = new RubyObject();
0076:
0077:            // The class of this object
0078:            protected RubyClass metaClass;
0079:
0080:            // The instance variables of this object.
0081:            protected Map instanceVariables;
0082:
0083:            private transient Object dataStruct;
0084:
0085:            // The two properties frozen and taint
0086:            private boolean frozen;
0087:            private boolean taint;
0088:            protected boolean isTrue = true;
0089:
0090:            private Finalizer finalizer;
0091:
0092:            public class Finalizer implements  Finalizable {
0093:                private long id;
0094:                private List finalizers;
0095:                private AtomicBoolean finalized;
0096:
0097:                public Finalizer(long id) {
0098:                    this .id = id;
0099:                    this .finalized = new AtomicBoolean(false);
0100:                }
0101:
0102:                public void addFinalizer(RubyProc finalizer) {
0103:                    if (finalizers == null) {
0104:                        finalizers = new ArrayList();
0105:                    }
0106:                    finalizers.add(finalizer);
0107:                }
0108:
0109:                public void removeFinalizers() {
0110:                    finalizers = null;
0111:                }
0112:
0113:                public void finalize() {
0114:                    if (finalized.compareAndSet(false, true)) {
0115:                        if (finalizers != null) {
0116:                            IRubyObject idFixnum = getRuntime().newFixnum(id);
0117:                            for (int i = 0; i < finalizers.size(); i++) {
0118:                                ((RubyProc) finalizers.get(i))
0119:                                        .call(new IRubyObject[] { idFixnum });
0120:                            }
0121:                        }
0122:                    }
0123:                }
0124:            }
0125:
0126:            public RubyObject(Ruby runtime, RubyClass metaClass) {
0127:                this (runtime, metaClass, runtime.isObjectSpaceEnabled());
0128:            }
0129:
0130:            public RubyObject(Ruby runtime, RubyClass metaClass,
0131:                    boolean useObjectSpace) {
0132:                this .metaClass = metaClass;
0133:                this .frozen = false;
0134:                this .taint = false;
0135:
0136:                // Do not store any immediate objects into objectspace.
0137:                if (useObjectSpace && !isImmediate()) {
0138:                    runtime.getObjectSpace().add(this );
0139:                }
0140:
0141:                // FIXME are there objects who shouldn't be tainted?
0142:                // (mri: OBJSETUP)
0143:                taint |= runtime.getSafeLevel() >= 3;
0144:            }
0145:
0146:            public static RubyClass createObjectClass(Ruby runtime,
0147:                    RubyClass objectClass) {
0148:                CallbackFactory callbackFactory = runtime
0149:                        .callbackFactory(RubyObject.class);
0150:                objectClass.index = ClassIndex.OBJECT;
0151:
0152:                objectClass.definePrivateMethod("initialize", callbackFactory
0153:                        .getOptMethod("initialize"));
0154:                objectClass.definePrivateMethod("inherited", callbackFactory
0155:                        .getMethod("inherited", IRubyObject.class));
0156:
0157:                return objectClass;
0158:            }
0159:
0160:            public static ObjectAllocator OBJECT_ALLOCATOR = new ObjectAllocator() {
0161:                public IRubyObject allocate(Ruby runtime, RubyClass klass) {
0162:                    IRubyObject instance = new RubyObject(runtime, klass);
0163:                    instance.setMetaClass(klass);
0164:
0165:                    return instance;
0166:                }
0167:            };
0168:
0169:            public void attachToObjectSpace() {
0170:                getRuntime().getObjectSpace().add(this );
0171:            }
0172:
0173:            /**
0174:             * This is overridden in the other concrete Java builtins to provide a fast way
0175:             * to determine what type they are.
0176:             */
0177:            public int getNativeTypeIndex() {
0178:                return ClassIndex.OBJECT;
0179:            }
0180:
0181:            /*
0182:             *  Is object immediate (def: Fixnum, Symbol, true, false, nil?).
0183:             */
0184:            public boolean isImmediate() {
0185:                return false;
0186:            }
0187:
0188:            /**
0189:             * Create a new meta class.
0190:             *
0191:             * @since Ruby 1.6.7
0192:             */
0193:            public RubyClass makeMetaClass(RubyClass super Class,
0194:                    SinglyLinkedList parentCRef) {
0195:                RubyClass klass = new MetaClass(getRuntime(), super Class,
0196:                        getMetaClass().getAllocator(), parentCRef);
0197:                setMetaClass(klass);
0198:
0199:                klass.setInstanceVariable("__attached__", this );
0200:
0201:                if (this  instanceof  RubyClass && isSingleton()) { // could be pulled down to RubyClass in future
0202:                    klass.setMetaClass(klass);
0203:                    klass.setSuperClass(((RubyClass) this ).getSuperClass()
0204:                            .getRealClass().getMetaClass());
0205:                } else {
0206:                    klass
0207:                            .setMetaClass(super Class.getRealClass()
0208:                                    .getMetaClass());
0209:                }
0210:
0211:                // use same ClassIndex as metaclass, since we're technically still of that type 
0212:                klass.index = super Class.index;
0213:                return klass;
0214:            }
0215:
0216:            public boolean isSingleton() {
0217:                return false;
0218:            }
0219:
0220:            public Class getJavaClass() {
0221:                return IRubyObject.class;
0222:            }
0223:
0224:            public static void puts(Object obj) {
0225:                System.out.println(obj.toString());
0226:            }
0227:
0228:            /**
0229:             * This method is just a wrapper around the Ruby "==" method,
0230:             * provided so that RubyObjects can be used as keys in the Java
0231:             * HashMap object underlying RubyHash.
0232:             */
0233:            public boolean equals(Object other) {
0234:                return other == this 
0235:                        || other instanceof  IRubyObject
0236:                        && callMethod(getRuntime().getCurrentContext(),
0237:                                MethodIndex.EQUALEQUAL, "==",
0238:                                (IRubyObject) other).isTrue();
0239:            }
0240:
0241:            public String toString() {
0242:                return callMethod(getRuntime().getCurrentContext(),
0243:                        MethodIndex.TO_S, "to_s", IRubyObject.NULL_ARRAY)
0244:                        .toString();
0245:            }
0246:
0247:            /** Getter for property ruby.
0248:             * @return Value of property ruby.
0249:             */
0250:            public Ruby getRuntime() {
0251:                return metaClass.getRuntime();
0252:            }
0253:
0254:            public boolean safeHasInstanceVariables() {
0255:                return instanceVariables != null
0256:                        && instanceVariables.size() > 0;
0257:            }
0258:
0259:            public Map safeGetInstanceVariables() {
0260:                return instanceVariables == null ? null
0261:                        : getInstanceVariablesSnapshot();
0262:            }
0263:
0264:            public IRubyObject removeInstanceVariable(String name) {
0265:                return (IRubyObject) getInstanceVariables().remove(name);
0266:            }
0267:
0268:            /**
0269:             * Returns an unmodifiable snapshot of the current state of instance variables.
0270:             * This method synchronizes access to avoid deadlocks.
0271:             */
0272:            public Map getInstanceVariablesSnapshot() {
0273:                synchronized (getInstanceVariables()) {
0274:                    return Collections.unmodifiableMap(new HashMap(
0275:                            getInstanceVariables()));
0276:                }
0277:            }
0278:
0279:            public Map getInstanceVariables() {
0280:                // TODO: double checking may or may not be safe enough here
0281:                if (instanceVariables == null) {
0282:                    synchronized (this ) {
0283:                        if (instanceVariables == null) {
0284:                            instanceVariables = Collections
0285:                                    .synchronizedMap(new HashMap());
0286:                        }
0287:                    }
0288:                }
0289:                return instanceVariables;
0290:            }
0291:
0292:            public void setInstanceVariables(Map instanceVariables) {
0293:                this .instanceVariables = Collections
0294:                        .synchronizedMap(instanceVariables);
0295:            }
0296:
0297:            /**
0298:             * if exist return the meta-class else return the type of the object.
0299:             *
0300:             */
0301:            public final RubyClass getMetaClass() {
0302:                return metaClass;
0303:            }
0304:
0305:            public void setMetaClass(RubyClass metaClass) {
0306:                this .metaClass = metaClass;
0307:            }
0308:
0309:            /**
0310:             * Gets the frozen.
0311:             * @return Returns a boolean
0312:             */
0313:            public boolean isFrozen() {
0314:                return frozen;
0315:            }
0316:
0317:            /**
0318:             * Sets the frozen.
0319:             * @param frozen The frozen to set
0320:             */
0321:            public void setFrozen(boolean frozen) {
0322:                this .frozen = frozen;
0323:            }
0324:
0325:            /** rb_frozen_class_p
0326:             *
0327:             */
0328:            protected void testFrozen(String message) {
0329:                if (isFrozen()) {
0330:                    throw getRuntime().newFrozenError(
0331:                            message + getMetaClass().getName());
0332:                }
0333:            }
0334:
0335:            protected void checkFrozen() {
0336:                testFrozen("can't modify frozen ");
0337:            }
0338:
0339:            /**
0340:             * Gets the taint.
0341:             * @return Returns a boolean
0342:             */
0343:            public boolean isTaint() {
0344:                return taint;
0345:            }
0346:
0347:            /**
0348:             * Sets the taint.
0349:             * @param taint The taint to set
0350:             */
0351:            public void setTaint(boolean taint) {
0352:                this .taint = taint;
0353:            }
0354:
0355:            public boolean isNil() {
0356:                return false;
0357:            }
0358:
0359:            public final boolean isTrue() {
0360:                return isTrue;
0361:            }
0362:
0363:            public final boolean isFalse() {
0364:                return !isTrue;
0365:            }
0366:
0367:            public boolean respondsTo(String name) {
0368:                if (getMetaClass().searchMethod("respond_to?") == getRuntime()
0369:                        .getRespondToMethod()) {
0370:                    return getMetaClass().isMethodBound(name, false);
0371:                } else {
0372:                    return callMethod(getRuntime().getCurrentContext(),
0373:                            "respond_to?", getRuntime().newSymbol(name))
0374:                            .isTrue();
0375:                }
0376:            }
0377:
0378:            public boolean isKindOf(RubyModule type) {
0379:                return getMetaClass().hasModuleInHierarchy(type);
0380:            }
0381:
0382:            /** rb_singleton_class
0383:             *
0384:             */
0385:            public RubyClass getSingletonClass() {
0386:                RubyClass klass;
0387:
0388:                if (getMetaClass().isSingleton()
0389:                        && getMetaClass().getInstanceVariable("__attached__") == this ) {
0390:                    klass = getMetaClass();
0391:                } else {
0392:                    klass = makeMetaClass(getMetaClass(), getMetaClass()
0393:                            .getCRef());
0394:                }
0395:
0396:                klass.setTaint(isTaint());
0397:                klass.setFrozen(isFrozen());
0398:
0399:                return klass;
0400:            }
0401:
0402:            /** rb_singleton_class_clone
0403:             *
0404:             */
0405:            public RubyClass getSingletonClassClone() {
0406:                RubyClass klass = getMetaClass();
0407:
0408:                if (!klass.isSingleton()) {
0409:                    return klass;
0410:                }
0411:
0412:                MetaClass clone = new MetaClass(getRuntime(), klass
0413:                        .getSuperClass(), getMetaClass().getAllocator(),
0414:                        getMetaClass().getCRef());
0415:                clone.setFrozen(klass.isFrozen());
0416:                clone.setTaint(klass.isTaint());
0417:
0418:                if (this  instanceof  RubyClass) {
0419:                    clone.setMetaClass(clone);
0420:                } else {
0421:                    clone.setMetaClass(klass.getSingletonClassClone());
0422:                }
0423:
0424:                if (klass.safeHasInstanceVariables()) {
0425:                    clone.setInstanceVariables(new HashMap(klass
0426:                            .getInstanceVariables()));
0427:                }
0428:
0429:                klass.cloneMethods(clone);
0430:
0431:                clone.getMetaClass().setInstanceVariable("__attached__", clone);
0432:
0433:                return clone;
0434:            }
0435:
0436:            /** init_copy
0437:             * 
0438:             */
0439:            public static void initCopy(IRubyObject clone, IRubyObject original) {
0440:                assert original != null;
0441:                assert !clone.isFrozen() : "frozen object ("
0442:                        + clone.getMetaClass().getName() + ") allocated";
0443:
0444:                if (original.safeHasInstanceVariables()) {
0445:                    clone.setInstanceVariables(new HashMap(original
0446:                            .getInstanceVariables()));
0447:                }
0448:
0449:                /* FIXME: finalizer should be dupped here */
0450:                clone.callMethod(clone.getRuntime().getCurrentContext(),
0451:                        "initialize_copy", original);
0452:            }
0453:
0454:            /** OBJ_INFECT
0455:             *
0456:             */
0457:            public IRubyObject infectBy(IRubyObject obj) {
0458:                setTaint(isTaint() || obj.isTaint());
0459:
0460:                return this ;
0461:            }
0462:
0463:            public IRubyObject callSuper(ThreadContext context,
0464:                    IRubyObject[] args, Block block) {
0465:                RubyModule klazz = context.getFrameKlazz();
0466:
0467:                RubyClass super Class = klazz.getSuperClass();
0468:
0469:                assert super Class != null : "Superclass should always be something for "
0470:                        + klazz.getBaseName();
0471:
0472:                return callMethod(context, super Class, context.getFrameName(),
0473:                        args, CallType.SUPER, block);
0474:            }
0475:
0476:            /**
0477:             *
0478:             */
0479:            public IRubyObject callMethod(ThreadContext context, String name,
0480:                    IRubyObject[] args) {
0481:                return callMethod(context, getMetaClass(), name, args,
0482:                        CallType.FUNCTIONAL, Block.NULL_BLOCK);
0483:            }
0484:
0485:            public IRubyObject callMethod(ThreadContext context, String name,
0486:                    IRubyObject[] args, Block block) {
0487:                return callMethod(context, getMetaClass(), name, args,
0488:                        CallType.FUNCTIONAL, block);
0489:            }
0490:
0491:            /**
0492:             *
0493:             */
0494:            public IRubyObject callMethod(ThreadContext context, String name,
0495:                    IRubyObject[] args, CallType callType) {
0496:                return callMethod(context, getMetaClass(), name, args,
0497:                        callType, Block.NULL_BLOCK);
0498:            }
0499:
0500:            public IRubyObject callMethod(ThreadContext context, String name,
0501:                    IRubyObject[] args, CallType callType, Block block) {
0502:                return callMethod(context, getMetaClass(), name, args,
0503:                        callType, block);
0504:            }
0505:
0506:            public IRubyObject callMethod(ThreadContext context,
0507:                    int methodIndex, String name, IRubyObject arg) {
0508:                return callMethod(context, getMetaClass(), methodIndex, name,
0509:                        new IRubyObject[] { arg }, CallType.FUNCTIONAL,
0510:                        Block.NULL_BLOCK);
0511:            }
0512:
0513:            public IRubyObject callMethod(ThreadContext context,
0514:                    int methodIndex, String name, IRubyObject[] args) {
0515:                return callMethod(context, getMetaClass(), methodIndex, name,
0516:                        args, CallType.FUNCTIONAL, Block.NULL_BLOCK);
0517:            }
0518:
0519:            public IRubyObject callMethod(ThreadContext context,
0520:                    int methodIndex, String name, IRubyObject[] args,
0521:                    CallType callType) {
0522:                return callMethod(context, getMetaClass(), methodIndex, name,
0523:                        args, callType, Block.NULL_BLOCK);
0524:            }
0525:
0526:            /**
0527:             * Used by the compiler to ease calling indexed methods, also to handle visibility.
0528:             * NOTE: THIS IS NOT THE SAME AS THE SWITCHVALUE VERSIONS.
0529:             */
0530:            public IRubyObject compilerCallMethodWithIndex(
0531:                    ThreadContext context, int methodIndex, String name,
0532:                    IRubyObject[] args, IRubyObject self, CallType callType,
0533:                    Block block) {
0534:                RubyModule module = getMetaClass();
0535:
0536:                if (module.index != 0) {
0537:                    return callMethod(context, module, methodIndex, name, args,
0538:                            callType, block);
0539:                }
0540:
0541:                return compilerCallMethod(context, name, args, self, callType,
0542:                        block);
0543:            }
0544:
0545:            /**
0546:             * Used by the compiler to handle visibility
0547:             */
0548:            public IRubyObject compilerCallMethod(ThreadContext context,
0549:                    String name, IRubyObject[] args, IRubyObject self,
0550:                    CallType callType, Block block) {
0551:                assert args != null;
0552:                DynamicMethod method = null;
0553:                RubyModule rubyclass = getMetaClass();
0554:                method = rubyclass.searchMethod(name);
0555:
0556:                if (method.isUndefined()
0557:                        || (!name.equals("method_missing") && !method
0558:                                .isCallableFrom(self, callType))) {
0559:                    return callMethodMissing(context, this , method, name, args,
0560:                            self, callType, block);
0561:                }
0562:
0563:                return method.call(context, this , rubyclass, name, args, false,
0564:                        block);
0565:            }
0566:
0567:            public static IRubyObject callMethodMissing(ThreadContext context,
0568:                    IRubyObject receiver, DynamicMethod method, String name,
0569:                    int methodIndex, IRubyObject[] args, IRubyObject self,
0570:                    CallType callType, Block block) {
0571:                // store call information so method_missing impl can use it            
0572:                context.setLastCallStatus(callType);
0573:                context.setLastVisibility(method.getVisibility());
0574:
0575:                if (methodIndex == MethodIndex.METHOD_MISSING) {
0576:                    return RubyKernel.method_missing(self, args, block);
0577:                }
0578:
0579:                IRubyObject[] newArgs = new IRubyObject[args.length + 1];
0580:                System.arraycopy(args, 0, newArgs, 1, args.length);
0581:                newArgs[0] = RubySymbol.newSymbol(self.getRuntime(), name);
0582:
0583:                return receiver.callMethod(context, "method_missing", newArgs,
0584:                        block);
0585:            }
0586:
0587:            public static IRubyObject callMethodMissing(ThreadContext context,
0588:                    IRubyObject receiver, DynamicMethod method, String name,
0589:                    IRubyObject[] args, IRubyObject self, CallType callType,
0590:                    Block block) {
0591:                // store call information so method_missing impl can use it            
0592:                context.setLastCallStatus(callType);
0593:                context.setLastVisibility(method.getVisibility());
0594:
0595:                if (name.equals("method_missing")) {
0596:                    return RubyKernel.method_missing(self, args, block);
0597:                }
0598:
0599:                IRubyObject[] newArgs = new IRubyObject[args.length + 1];
0600:                System.arraycopy(args, 0, newArgs, 1, args.length);
0601:                newArgs[0] = RubySymbol.newSymbol(self.getRuntime(), name);
0602:
0603:                return receiver.callMethod(context, "method_missing", newArgs,
0604:                        block);
0605:            }
0606:
0607:            /**
0608:             *
0609:             */
0610:            public IRubyObject callMethod(ThreadContext context,
0611:                    RubyModule rubyclass, int methodIndex, String name,
0612:                    IRubyObject[] args, CallType callType) {
0613:                return callMethod(context, rubyclass, methodIndex, name, args,
0614:                        callType, Block.NULL_BLOCK);
0615:            }
0616:
0617:            /**
0618:             *
0619:             */
0620:            public IRubyObject callMethod(ThreadContext context,
0621:                    RubyModule rubyclass, int methodIndex, String name,
0622:                    IRubyObject[] args, CallType callType, Block block) {
0623:                return callMethod(context, rubyclass, name, args, callType,
0624:                        block);
0625:            }
0626:
0627:            /**
0628:             *
0629:             */
0630:            public IRubyObject callMethod(ThreadContext context,
0631:                    RubyModule rubyclass, String name, IRubyObject[] args,
0632:                    CallType callType, Block block) {
0633:                assert args != null;
0634:                DynamicMethod method = null;
0635:                method = rubyclass.searchMethod(name);
0636:
0637:                if (method.isUndefined()
0638:                        || (!name.equals("method_missing") && !method
0639:                                .isCallableFrom(context.getFrameSelf(),
0640:                                        callType))) {
0641:                    return callMethodMissing(context, this , method, name, args,
0642:                            context.getFrameSelf(), callType, block);
0643:                }
0644:
0645:                return method.call(context, this , rubyclass, name, args, false,
0646:                        block);
0647:            }
0648:
0649:            public IRubyObject callMethod(ThreadContext context, String name) {
0650:                return callMethod(context, getMetaClass(), name,
0651:                        IRubyObject.NULL_ARRAY, null, Block.NULL_BLOCK);
0652:            }
0653:
0654:            public IRubyObject callMethod(ThreadContext context,
0655:                    int methodIndex, String name) {
0656:                return callMethod(context, getMetaClass(), methodIndex, name,
0657:                        IRubyObject.NULL_ARRAY, null, Block.NULL_BLOCK);
0658:            }
0659:
0660:            public IRubyObject callMethod(ThreadContext context, String name,
0661:                    Block block) {
0662:                return callMethod(context, getMetaClass(), name,
0663:                        IRubyObject.NULL_ARRAY, null, block);
0664:            }
0665:
0666:            /**
0667:             * rb_funcall
0668:             *
0669:             */
0670:            public IRubyObject callMethod(ThreadContext context, String name,
0671:                    IRubyObject arg) {
0672:                return callMethod(context, name, new IRubyObject[] { arg });
0673:            }
0674:
0675:            public IRubyObject instance_variable_get(IRubyObject var) {
0676:                String varName = var.asSymbol();
0677:
0678:                if (!IdUtil.isInstanceVariable(varName)) {
0679:                    throw getRuntime()
0680:                            .newNameError(
0681:                                    "`"
0682:                                            + varName
0683:                                            + "' is not allowable as an instance variable name",
0684:                                    varName);
0685:                }
0686:
0687:                IRubyObject variable = getInstanceVariable(varName);
0688:
0689:                // Pickaxe v2 says no var should show NameError, but ruby only sends back nil..
0690:                return variable == null ? getRuntime().getNil() : variable;
0691:            }
0692:
0693:            public IRubyObject getInstanceVariable(String name) {
0694:                return (IRubyObject) getInstanceVariables().get(name);
0695:            }
0696:
0697:            public IRubyObject instance_variable_set(IRubyObject var,
0698:                    IRubyObject value) {
0699:                String varName = var.asSymbol();
0700:
0701:                if (!IdUtil.isInstanceVariable(varName)) {
0702:                    throw getRuntime()
0703:                            .newNameError(
0704:                                    "`"
0705:                                            + varName
0706:                                            + "' is not allowable as an instance variable name",
0707:                                    varName);
0708:                }
0709:
0710:                return setInstanceVariable(var.asSymbol(), value);
0711:            }
0712:
0713:            public IRubyObject setInstanceVariable(String name,
0714:                    IRubyObject value, String taintError, String freezeError) {
0715:                if (isTaint() && getRuntime().getSafeLevel() >= 4) {
0716:                    throw getRuntime().newSecurityError(taintError);
0717:                }
0718:                testFrozen(freezeError);
0719:
0720:                getInstanceVariables().put(name, value);
0721:
0722:                return value;
0723:            }
0724:
0725:            /** rb_iv_set / rb_ivar_set
0726:             *
0727:             */
0728:            public IRubyObject setInstanceVariable(String name,
0729:                    IRubyObject value) {
0730:                return setInstanceVariable(name, value,
0731:                        "Insecure: can't modify instance variable", "");
0732:            }
0733:
0734:            public Iterator instanceVariableNames() {
0735:                return getInstanceVariables().keySet().iterator();
0736:            }
0737:
0738:            public void callInit(IRubyObject[] args, Block block) {
0739:                callMethod(getRuntime().getCurrentContext(), "initialize",
0740:                        args, block);
0741:            }
0742:
0743:            /** rb_to_id
0744:             *
0745:             */
0746:            public String asSymbol() {
0747:                throw getRuntime().newTypeError(
0748:                        inspect().toString() + " is not a symbol");
0749:            }
0750:
0751:            public static String trueFalseNil(IRubyObject v) {
0752:                return trueFalseNil(v.getMetaClass().getRealClass().getName());
0753:            }
0754:
0755:            public static String trueFalseNil(String v) {
0756:                if ("TrueClass".equals(v)) {
0757:                    return "true";
0758:                } else if ("FalseClass".equals(v)) {
0759:                    return "false";
0760:                } else if ("NilClass".equals(v)) {
0761:                    return "nil";
0762:                }
0763:                return v;
0764:            }
0765:
0766:            public RubyArray convertToArray() {
0767:                return (RubyArray) convertToType(getRuntime().getArray(),
0768:                        MethodIndex.TO_ARY, true);
0769:            }
0770:
0771:            public RubyHash convertToHash() {
0772:                return (RubyHash) convertToType(getRuntime().getHash(),
0773:                        MethodIndex.TO_HASH, "to_hash", true, true, false);
0774:            }
0775:
0776:            public RubyFloat convertToFloat() {
0777:                return (RubyFloat) convertToType(
0778:                        getRuntime().getClass("Float"), MethodIndex.TO_F, true);
0779:            }
0780:
0781:            public RubyInteger convertToInteger() {
0782:                return (RubyInteger) convertToType(getRuntime().getClass(
0783:                        "Integer"), MethodIndex.TO_INT, true);
0784:            }
0785:
0786:            public RubyString convertToString() {
0787:                return (RubyString) convertToType(getRuntime().getString(),
0788:                        MethodIndex.TO_STR, true);
0789:            }
0790:
0791:            /*
0792:             * @see org.jruby.runtime.builtin.IRubyObject#convertToTypeWithCheck(java.lang.String, java.lang.String)
0793:             */
0794:            public IRubyObject convertToTypeWithCheck(RubyClass targetType,
0795:                    int convertMethodIndex, String convertMethod) {
0796:                return convertToType(targetType, convertMethodIndex,
0797:                        convertMethod, false, true, true);
0798:            }
0799:
0800:            /*
0801:             * @see org.jruby.runtime.builtin.IRubyObject#convertToType(java.lang.String, java.lang.String, boolean)
0802:             */
0803:            public IRubyObject convertToType(RubyClass targetType,
0804:                    int convertMethodIndex, String convertMethod, boolean raise) {
0805:                return convertToType(targetType, convertMethodIndex,
0806:                        convertMethod, raise, false, false);
0807:            }
0808:
0809:            /*
0810:             * @see org.jruby.runtime.builtin.IRubyObject#convertToType(java.lang.String, java.lang.String, boolean)
0811:             */
0812:            public IRubyObject convertToType(RubyClass targetType,
0813:                    int convertMethodIndex, boolean raise) {
0814:                return convertToType(targetType, convertMethodIndex,
0815:                        MethodIndex.NAMES[convertMethodIndex], raise, true,
0816:                        false);
0817:            }
0818:
0819:            public IRubyObject convertToType(RubyClass targetType,
0820:                    int convertMethodIndex, String convertMethod,
0821:                    boolean raiseOnMissingMethod,
0822:                    boolean raiseOnWrongTypeResult, boolean allowNilThrough) {
0823:                if (isKindOf(targetType)) {
0824:                    return this ;
0825:                }
0826:
0827:                if (!respondsTo(convertMethod)) {
0828:                    if (raiseOnMissingMethod) {
0829:                        throw getRuntime().newTypeError(
0830:                                "can't convert " + trueFalseNil(this )
0831:                                        + " into "
0832:                                        + trueFalseNil(targetType.getName()));
0833:                    }
0834:
0835:                    return getRuntime().getNil();
0836:                }
0837:
0838:                IRubyObject value = callMethod(
0839:                        getRuntime().getCurrentContext(), convertMethodIndex,
0840:                        convertMethod, IRubyObject.NULL_ARRAY);
0841:
0842:                if (allowNilThrough && value.isNil()) {
0843:                    return value;
0844:                }
0845:
0846:                if (raiseOnWrongTypeResult && !value.isKindOf(targetType)) {
0847:                    throw getRuntime().newTypeError(
0848:                            getMetaClass().getName() + "#" + convertMethod
0849:                                    + " should return " + targetType);
0850:                }
0851:
0852:                return value;
0853:            }
0854:
0855:            /** rb_obj_as_string
0856:             */
0857:            public RubyString asString() {
0858:                if (this  instanceof  RubyString)
0859:                    return (RubyString) this ;
0860:
0861:                IRubyObject str = this .callMethod(getRuntime()
0862:                        .getCurrentContext(), MethodIndex.TO_S, "to_s",
0863:                        IRubyObject.NULL_ARRAY);
0864:
0865:                if (!(str instanceof  RubyString))
0866:                    str = anyToString();
0867:
0868:                return (RubyString) str;
0869:            }
0870:
0871:            /** rb_check_string_type
0872:             *
0873:             */
0874:            public IRubyObject checkStringType() {
0875:                IRubyObject str = convertToTypeWithCheck(getRuntime()
0876:                        .getString(), MethodIndex.TO_STR, "to_str");
0877:                if (!str.isNil() && !(str instanceof  RubyString)) {
0878:                    str = getRuntime().newString("");
0879:                }
0880:                return str;
0881:            }
0882:
0883:            /** rb_check_array_type
0884:             *
0885:             */
0886:            public IRubyObject checkArrayType() {
0887:                return convertToTypeWithCheck(getRuntime().getArray(),
0888:                        MethodIndex.TO_ARY, "to_ary");
0889:            }
0890:
0891:            /** specific_eval
0892:             *
0893:             */
0894:            public IRubyObject specificEval(RubyModule mod, IRubyObject[] args,
0895:                    Block block) {
0896:                if (block.isGiven()) {
0897:                    if (args.length > 0)
0898:                        throw getRuntime().newArgumentError(args.length, 0);
0899:
0900:                    return yieldUnder(mod, new IRubyObject[] { this  }, block);
0901:                }
0902:                ThreadContext tc = getRuntime().getCurrentContext();
0903:
0904:                if (args.length == 0) {
0905:                    throw getRuntime().newArgumentError("block not supplied");
0906:                } else if (args.length > 3) {
0907:                    String lastFuncName = tc.getFrameName();
0908:                    throw getRuntime().newArgumentError(
0909:                            "wrong # of arguments: " + lastFuncName
0910:                                    + "(src) or " + lastFuncName + "{..}");
0911:                }
0912:                /*
0913:                if (ruby.getSecurityLevel() >= 4) {
0914:                	Check_Type(argv[0], T_STRING);
0915:                } else {
0916:                	Check_SafeStr(argv[0]);
0917:                }
0918:                 */
0919:
0920:                // We just want the TypeError if the argument doesn't convert to a String (JRUBY-386)
0921:                args[0].convertToString();
0922:
0923:                IRubyObject file = args.length > 1 ? args[1] : getRuntime()
0924:                        .newString("(eval)");
0925:                IRubyObject line = args.length > 2 ? args[2] : RubyFixnum
0926:                        .one(getRuntime());
0927:
0928:                Visibility savedVisibility = tc.getCurrentVisibility();
0929:                tc.setCurrentVisibility(Visibility.PUBLIC);
0930:                try {
0931:                    return evalUnder(mod, args[0], file, line);
0932:                } finally {
0933:                    tc.setCurrentVisibility(savedVisibility);
0934:                }
0935:            }
0936:
0937:            public IRubyObject evalUnder(RubyModule under, IRubyObject src,
0938:                    IRubyObject file, IRubyObject line) {
0939:                return under.executeUnder(new Callback() {
0940:                    public IRubyObject execute(IRubyObject self,
0941:                            IRubyObject[] args, Block block) {
0942:                        IRubyObject source = args[1];
0943:                        IRubyObject filename = args[2];
0944:                        // FIXME: lineNumber is not supported
0945:                        //IRubyObject lineNumber = args[3];
0946:
0947:                        return args[0].evalSimple(source.getRuntime()
0948:                                .getCurrentContext(), source, filename
0949:                                .convertToString().toString());
0950:                    }
0951:
0952:                    public Arity getArity() {
0953:                        return Arity.optional();
0954:                    }
0955:                }, new IRubyObject[] { this , src, file, line },
0956:                        Block.NULL_BLOCK);
0957:            }
0958:
0959:            private IRubyObject yieldUnder(RubyModule under,
0960:                    IRubyObject[] args, Block block) {
0961:                final IRubyObject selfInYield = this ;
0962:                return under.executeUnder(new Callback() {
0963:                    public IRubyObject execute(IRubyObject self,
0964:                            IRubyObject[] args, Block block) {
0965:                        ThreadContext context = getRuntime()
0966:                                .getCurrentContext();
0967:
0968:                        Visibility savedVisibility = block.getVisibility();
0969:
0970:                        block.setVisibility(Visibility.PUBLIC);
0971:                        try {
0972:                            IRubyObject valueInYield;
0973:                            boolean aValue;
0974:                            if (args.length == 1) {
0975:                                valueInYield = args[0];
0976:                                aValue = false;
0977:                            } else {
0978:                                valueInYield = RubyArray.newArray(getRuntime(),
0979:                                        args);
0980:                                aValue = true;
0981:                            }
0982:                            return block
0983:                                    .yield(context, valueInYield, selfInYield,
0984:                                            context.getRubyClass(), aValue);
0985:                            //TODO: Should next and return also catch here?
0986:                        } catch (JumpException je) {
0987:                            if (je.getJumpType() == JumpException.JumpType.BreakJump) {
0988:                                return (IRubyObject) je.getValue();
0989:                            }
0990:
0991:                            throw je;
0992:                        } finally {
0993:                            block.setVisibility(savedVisibility);
0994:                        }
0995:                    }
0996:
0997:                    public Arity getArity() {
0998:                        return Arity.optional();
0999:                    }
1000:                }, args, block);
1001:            }
1002:
1003:            /* (non-Javadoc)
1004:             * @see org.jruby.runtime.builtin.IRubyObject#evalWithBinding(org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject, java.lang.String)
1005:             */
1006:            public IRubyObject evalWithBinding(ThreadContext context,
1007:                    IRubyObject src, IRubyObject scope, String file,
1008:                    int lineNumber) {
1009:                // both of these are ensured by the (very few) callers
1010:                assert !scope.isNil();
1011:                assert file != null;
1012:
1013:                ThreadContext threadContext = getRuntime().getCurrentContext();
1014:                ISourcePosition savedPosition = threadContext.getPosition();
1015:
1016:                if (!(scope instanceof  RubyBinding)) {
1017:                    if (scope instanceof  RubyProc) {
1018:                        scope = ((RubyProc) scope).binding();
1019:                    } else {
1020:                        // bomb out, it's not a binding or a proc
1021:                        throw getRuntime().newTypeError(
1022:                                "wrong argument type " + scope.getMetaClass()
1023:                                        + " (expected Proc/Binding)");
1024:                    }
1025:                }
1026:
1027:                Block blockOfBinding = ((RubyBinding) scope).getBlock();
1028:                try {
1029:                    // Binding provided for scope, use it
1030:                    threadContext.preEvalWithBinding(blockOfBinding);
1031:                    IRubyObject newSelf = threadContext.getFrameSelf();
1032:                    Node node = getRuntime().parse(src.toString(), file,
1033:                            blockOfBinding.getDynamicScope(), lineNumber);
1034:
1035:                    return EvaluationState.eval(getRuntime(), threadContext,
1036:                            node, newSelf, blockOfBinding);
1037:                } catch (JumpException je) {
1038:                    if (je.getJumpType() == JumpException.JumpType.BreakJump) {
1039:                        throw getRuntime()
1040:                                .newLocalJumpError("break",
1041:                                        (IRubyObject) je.getValue(),
1042:                                        "unexpected break");
1043:                    }
1044:                    throw je;
1045:                } finally {
1046:                    threadContext.postEvalWithBinding(blockOfBinding);
1047:
1048:                    // restore position
1049:                    threadContext.setPosition(savedPosition);
1050:                }
1051:            }
1052:
1053:            /* (non-Javadoc)
1054:             * @see org.jruby.runtime.builtin.IRubyObject#evalSimple(org.jruby.runtime.builtin.IRubyObject, java.lang.String)
1055:             */
1056:            public IRubyObject evalSimple(ThreadContext context,
1057:                    IRubyObject src, String file) {
1058:                // this is ensured by the callers
1059:                assert file != null;
1060:
1061:                ISourcePosition savedPosition = context.getPosition();
1062:
1063:                // no binding, just eval in "current" frame (caller's frame)
1064:                try {
1065:                    Node node = getRuntime().parse(src.toString(), file,
1066:                            context.getCurrentScope(), 0);
1067:
1068:                    return EvaluationState.eval(getRuntime(), context, node,
1069:                            this , Block.NULL_BLOCK);
1070:                } catch (JumpException je) {
1071:                    if (je.getJumpType() == JumpException.JumpType.BreakJump) {
1072:                        throw getRuntime()
1073:                                .newLocalJumpError("break",
1074:                                        (IRubyObject) je.getValue(),
1075:                                        "unexpected break");
1076:                    }
1077:                    throw je;
1078:                } finally {
1079:                    // restore position
1080:                    context.setPosition(savedPosition);
1081:                }
1082:            }
1083:
1084:            // Methods of the Object class (rb_obj_*):
1085:
1086:            /** rb_obj_equal
1087:             *
1088:             */
1089:            public IRubyObject obj_equal(IRubyObject obj) {
1090:                return this  == obj ? getRuntime().getTrue() : getRuntime()
1091:                        .getFalse();
1092:            }
1093:
1094:            /** rb_equal
1095:             * 
1096:             */
1097:            public IRubyObject equal(IRubyObject other) {
1098:                if (this  == other
1099:                        || callMethod(getRuntime().getCurrentContext(),
1100:                                MethodIndex.EQUALEQUAL, "==", other).isTrue()) {
1101:                    return getRuntime().getTrue();
1102:                }
1103:
1104:                return getRuntime().getFalse();
1105:            }
1106:
1107:            public final IRubyObject equalInternal(final ThreadContext context,
1108:                    final IRubyObject other) {
1109:                if (this  == other)
1110:                    return getRuntime().getTrue();
1111:                return callMethod(context, MethodIndex.EQUALEQUAL, "==", other);
1112:            }
1113:
1114:            /** rb_eql
1115:             *  this method is not defind for Ruby objects directly.
1116:             *  notably overriden by RubyFixnum, RubyString, RubySymbol - these do a short-circuit calls.
1117:             *  see: rb_any_cmp() in hash.c
1118:             *  do not confuse this method with eql_p methods (which it calls by default), eql is mainly used for hash key comparison 
1119:             */
1120:            public boolean eql(IRubyObject other) {
1121:                return callMethod(getRuntime().getCurrentContext(),
1122:                        MethodIndex.EQL_P, "eql?", other).isTrue();
1123:            }
1124:
1125:            public final boolean eqlInternal(final ThreadContext context,
1126:                    final IRubyObject other) {
1127:                if (this  == other)
1128:                    return true;
1129:                return callMethod(context, MethodIndex.EQL_P, "eql?", other)
1130:                        .isTrue();
1131:            }
1132:
1133:            /** rb_obj_init_copy
1134:             * 
1135:             */
1136:            public IRubyObject initialize_copy(IRubyObject original) {
1137:                if (this  == original)
1138:                    return this ;
1139:
1140:                checkFrozen();
1141:
1142:                if (getMetaClass().getRealClass() != original.getMetaClass()
1143:                        .getRealClass()) {
1144:                    throw getRuntime().newTypeError(
1145:                            "initialize_copy should take same class object");
1146:                }
1147:
1148:                return this ;
1149:            }
1150:
1151:            /**
1152:             * respond_to?( aSymbol, includePriv=false ) -> true or false
1153:             *
1154:             * Returns true if this object responds to the given method. Private
1155:             * methods are included in the search only if the optional second
1156:             * parameter evaluates to true.
1157:             *
1158:             * @return true if this responds to the given method
1159:             */
1160:            public RubyBoolean respond_to(IRubyObject[] args) {
1161:                Arity.checkArgumentCount(getRuntime(), args, 1, 2);
1162:
1163:                String name = args[0].asSymbol();
1164:                boolean includePrivate = args.length > 1 ? args[1].isTrue()
1165:                        : false;
1166:
1167:                return getRuntime().newBoolean(
1168:                        getMetaClass().isMethodBound(name, !includePrivate));
1169:            }
1170:
1171:            /** Return the internal id of an object.
1172:             *
1173:             * <i>CRuby function: rb_obj_id</i>
1174:             *
1175:             */
1176:            public synchronized RubyFixnum id() {
1177:                return getRuntime().newFixnum(
1178:                        getRuntime().getObjectSpace().idOf(this ));
1179:            }
1180:
1181:            public synchronized RubyFixnum id_deprecated() {
1182:                getRuntime().getWarnings().warn(
1183:                        "Object#id will be deprecated; use Object#object_id");
1184:                return getRuntime().newFixnum(
1185:                        getRuntime().getObjectSpace().idOf(this ));
1186:            }
1187:
1188:            public RubyFixnum hash() {
1189:                return getRuntime().newFixnum(super .hashCode());
1190:            }
1191:
1192:            public int hashCode() {
1193:                IRubyObject hashValue = callMethod(getRuntime()
1194:                        .getCurrentContext(), MethodIndex.HASH, "hash");
1195:
1196:                if (hashValue instanceof  RubyFixnum)
1197:                    return (int) RubyNumeric.fix2long(hashValue);
1198:
1199:                return super .hashCode();
1200:            }
1201:
1202:            /** rb_obj_type
1203:             *
1204:             */
1205:            public RubyClass type() {
1206:                return getMetaClass().getRealClass();
1207:            }
1208:
1209:            public RubyClass type_deprecated() {
1210:                getRuntime().getWarnings().warn(
1211:                        "Object#type is deprecated; use Object#class");
1212:                return type();
1213:            }
1214:
1215:            /** rb_obj_clone
1216:             *  should be overriden only by: Proc, Method, UnboundedMethod, Binding
1217:             */
1218:            public IRubyObject rbClone(Block unusedBlock) {
1219:                if (isImmediate()) { // rb_special_const_p(obj) equivalent
1220:                    throw getRuntime().newTypeError(
1221:                            "can't clone " + getMetaClass().getName());
1222:                }
1223:
1224:                IRubyObject clone = doClone();
1225:                clone.setMetaClass(getSingletonClassClone());
1226:                clone.setTaint(isTaint());
1227:                initCopy(clone, this );
1228:                clone.setFrozen(isFrozen());
1229:                return clone;
1230:            }
1231:
1232:            // Hack: allow RubyModule and RubyClass to override the allocation and return the the correct Java instance
1233:            // Cloning a class object doesn't work otherwise and I don't really understand why --sma
1234:            protected IRubyObject doClone() {
1235:                RubyClass realClass = getMetaClass().getRealClass();
1236:                return realClass.getAllocator().allocate(getRuntime(),
1237:                        realClass);
1238:            }
1239:
1240:            public IRubyObject display(IRubyObject[] args) {
1241:                IRubyObject port = args.length == 0 ? getRuntime()
1242:                        .getGlobalVariables().get("$>") : args[0];
1243:
1244:                port
1245:                        .callMethod(getRuntime().getCurrentContext(), "write",
1246:                                this );
1247:
1248:                return getRuntime().getNil();
1249:            }
1250:
1251:            /** rb_obj_dup
1252:             *  should be overriden only by: Proc
1253:             */
1254:            public IRubyObject dup() {
1255:                if (isImmediate()) {
1256:                    throw getRuntime().newTypeError(
1257:                            "can't dup " + getMetaClass().getName());
1258:                }
1259:
1260:                IRubyObject dup = doClone();
1261:
1262:                dup.setMetaClass(type());
1263:                dup.setFrozen(false);
1264:                dup.setTaint(isTaint());
1265:
1266:                initCopy(dup, this );
1267:
1268:                return dup;
1269:            }
1270:
1271:            /** rb_obj_tainted
1272:             *
1273:             */
1274:            public RubyBoolean tainted() {
1275:                return getRuntime().newBoolean(isTaint());
1276:            }
1277:
1278:            /** rb_obj_taint
1279:             *
1280:             */
1281:            public IRubyObject taint() {
1282:                getRuntime().secure(4);
1283:                if (!isTaint()) {
1284:                    testFrozen("object");
1285:                    setTaint(true);
1286:                }
1287:                return this ;
1288:            }
1289:
1290:            /** rb_obj_untaint
1291:             *
1292:             */
1293:            public IRubyObject untaint() {
1294:                getRuntime().secure(3);
1295:                if (isTaint()) {
1296:                    testFrozen("object");
1297:                    setTaint(false);
1298:                }
1299:                return this ;
1300:            }
1301:
1302:            /** Freeze an object.
1303:             *
1304:             * rb_obj_freeze
1305:             *
1306:             */
1307:            public IRubyObject freeze() {
1308:                if (getRuntime().getSafeLevel() >= 4 && isTaint()) {
1309:                    throw getRuntime().newSecurityError(
1310:                            "Insecure: can't freeze object");
1311:                }
1312:                setFrozen(true);
1313:                return this ;
1314:            }
1315:
1316:            /** rb_obj_frozen_p
1317:             *
1318:             */
1319:            public RubyBoolean frozen() {
1320:                return getRuntime().newBoolean(isFrozen());
1321:            }
1322:
1323:            /** rb_obj_inspect
1324:             *
1325:             */
1326:            public IRubyObject inspect() {
1327:                if ((!isImmediate())
1328:                        &&
1329:                        // TYPE(obj) == T_OBJECT
1330:                        !(this  instanceof  RubyClass)
1331:                        && this  != getRuntime().getObject()
1332:                        && this  != getRuntime().getClass("Module")
1333:                        && !(this  instanceof  RubyModule)
1334:                        && safeHasInstanceVariables()) {
1335:
1336:                    StringBuffer part = new StringBuffer();
1337:                    String cname = getMetaClass().getRealClass().getName();
1338:                    part.append("#<").append(cname).append(":0x");
1339:                    part.append(Integer.toHexString(System
1340:                            .identityHashCode(this )));
1341:                    if (!getRuntime().registerInspecting(this )) {
1342:                        /* 6:tags 16:addr 1:eos */
1343:                        part.append(" ...>");
1344:                        return getRuntime().newString(part.toString());
1345:                    }
1346:                    try {
1347:                        String sep = "";
1348:                        Map iVars = getInstanceVariablesSnapshot();
1349:                        for (Iterator iter = iVars.keySet().iterator(); iter
1350:                                .hasNext();) {
1351:                            String name = (String) iter.next();
1352:                            if (IdUtil.isInstanceVariable(name)) {
1353:                                part.append(sep);
1354:                                part.append(" ");
1355:                                part.append(name);
1356:                                part.append("=");
1357:                                part
1358:                                        .append(((IRubyObject) (iVars.get(name)))
1359:                                                .callMethod(getRuntime()
1360:                                                        .getCurrentContext(),
1361:                                                        "inspect"));
1362:                                sep = ",";
1363:                            }
1364:                        }
1365:                        part.append(">");
1366:                        return getRuntime().newString(part.toString());
1367:                    } finally {
1368:                        getRuntime().unregisterInspecting(this );
1369:                    }
1370:                }
1371:
1372:                if (isNil())
1373:                    return RubyNil.inspect(this );
1374:                return callMethod(getRuntime().getCurrentContext(),
1375:                        MethodIndex.TO_S, "to_s", IRubyObject.NULL_ARRAY);
1376:            }
1377:
1378:            /** rb_obj_is_instance_of
1379:             *
1380:             */
1381:            public RubyBoolean instance_of(IRubyObject type) {
1382:                return getRuntime().newBoolean(type() == type);
1383:            }
1384:
1385:            public RubyArray instance_variables() {
1386:                ArrayList names = new ArrayList();
1387:                for (Iterator iter = getInstanceVariablesSnapshot().keySet()
1388:                        .iterator(); iter.hasNext();) {
1389:                    String name = (String) iter.next();
1390:
1391:                    // Do not include constants which also get stored in instance var list in classes.
1392:                    if (IdUtil.isInstanceVariable(name)) {
1393:                        names.add(getRuntime().newString(name));
1394:                    }
1395:                }
1396:                return getRuntime().newArray(names);
1397:            }
1398:
1399:            /** rb_obj_is_kind_of
1400:             *
1401:             */
1402:            public RubyBoolean kind_of(IRubyObject type) {
1403:                // TODO: Generalize this type-checking code into IRubyObject helper.
1404:                if (!type.isKindOf(getRuntime().getClass("Module"))) {
1405:                    // TODO: newTypeError does not offer enough for ruby error string...
1406:                    throw getRuntime().newTypeError(type,
1407:                            getRuntime().getClass("Module"));
1408:                }
1409:
1410:                return getRuntime().newBoolean(isKindOf((RubyModule) type));
1411:            }
1412:
1413:            /** rb_obj_methods
1414:             *
1415:             */
1416:            public IRubyObject methods(IRubyObject[] args) {
1417:                Arity.checkArgumentCount(getRuntime(), args, 0, 1);
1418:
1419:                if (args.length == 0) {
1420:                    args = new IRubyObject[] { getRuntime().getTrue() };
1421:                }
1422:
1423:                return getMetaClass().instance_methods(args);
1424:            }
1425:
1426:            public IRubyObject public_methods(IRubyObject[] args) {
1427:                Arity.checkArgumentCount(getRuntime(), args, 0, 1);
1428:
1429:                if (args.length == 0) {
1430:                    args = new IRubyObject[] { getRuntime().getTrue() };
1431:                }
1432:
1433:                return getMetaClass().public_instance_methods(args);
1434:            }
1435:
1436:            /** rb_obj_protected_methods
1437:             *
1438:             */
1439:            public IRubyObject protected_methods(IRubyObject[] args) {
1440:                Arity.checkArgumentCount(getRuntime(), args, 0, 1);
1441:
1442:                if (args.length == 0) {
1443:                    args = new IRubyObject[] { getRuntime().getTrue() };
1444:                }
1445:
1446:                return getMetaClass().protected_instance_methods(args);
1447:            }
1448:
1449:            /** rb_obj_private_methods
1450:             *
1451:             */
1452:            public IRubyObject private_methods(IRubyObject[] args) {
1453:                Arity.checkArgumentCount(getRuntime(), args, 0, 1);
1454:
1455:                if (args.length == 0) {
1456:                    args = new IRubyObject[] { getRuntime().getTrue() };
1457:                }
1458:
1459:                return getMetaClass().private_instance_methods(args);
1460:            }
1461:
1462:            /** rb_obj_singleton_methods
1463:             *
1464:             */
1465:            // TODO: This is almost RubyModule#instance_methods on the metaClass.  Perhaps refactor.
1466:            public RubyArray singleton_methods(IRubyObject[] args) {
1467:                boolean all = true;
1468:                if (Arity.checkArgumentCount(getRuntime(), args, 0, 1) == 1) {
1469:                    all = args[0].isTrue();
1470:                }
1471:
1472:                RubyArray result = getRuntime().newArray();
1473:
1474:                for (RubyClass type = getMetaClass(); type != null
1475:                        && ((type instanceof  MetaClass) || (all && type
1476:                                .isIncluded())); type = type.getSuperClass()) {
1477:                    for (Iterator iter = type.getMethods().entrySet()
1478:                            .iterator(); iter.hasNext();) {
1479:                        Map.Entry entry = (Map.Entry) iter.next();
1480:                        DynamicMethod method = (DynamicMethod) entry.getValue();
1481:
1482:                        // We do not want to capture cached methods
1483:                        if (method.getImplementationClass() != type
1484:                                && !(all && type.isIncluded())) {
1485:                            continue;
1486:                        }
1487:
1488:                        RubyString methodName = getRuntime().newString(
1489:                                (String) entry.getKey());
1490:                        if (method.getVisibility().isPublic()
1491:                                && !result.includes(methodName)) {
1492:                            result.append(methodName);
1493:                        }
1494:                    }
1495:                }
1496:
1497:                return result;
1498:            }
1499:
1500:            public IRubyObject method(IRubyObject symbol) {
1501:                return getMetaClass().newMethod(this , symbol.asSymbol(), true);
1502:            }
1503:
1504:            public IRubyObject anyToString() {
1505:                String cname = getMetaClass().getRealClass().getName();
1506:                /* 6:tags 16:addr 1:eos */
1507:                RubyString str = getRuntime().newString(
1508:                        "#<"
1509:                                + cname
1510:                                + ":0x"
1511:                                + Integer.toHexString(System
1512:                                        .identityHashCode(this )) + ">");
1513:                str.setTaint(isTaint());
1514:                return str;
1515:            }
1516:
1517:            public IRubyObject to_s() {
1518:                return anyToString();
1519:            }
1520:
1521:            public IRubyObject instance_eval(IRubyObject[] args, Block block) {
1522:                return specificEval(getSingletonClass(), args, block);
1523:            }
1524:
1525:            public IRubyObject instance_exec(IRubyObject[] args, Block block) {
1526:                if (!block.isGiven()) {
1527:                    throw getRuntime().newArgumentError("block not supplied");
1528:                }
1529:                return yieldUnder(getSingletonClass(), args, block);
1530:            }
1531:
1532:            public IRubyObject extend(IRubyObject[] args) {
1533:                Arity.checkArgumentCount(getRuntime(), args, 1, -1);
1534:
1535:                // Make sure all arguments are modules before calling the callbacks
1536:                for (int i = 0; i < args.length; i++) {
1537:                    IRubyObject obj;
1538:                    if (!(((obj = args[i]) instanceof  RubyModule) && ((RubyModule) obj)
1539:                            .isModule())) {
1540:                        throw getRuntime().newTypeError(obj,
1541:                                getRuntime().getClass("Module"));
1542:                    }
1543:                }
1544:
1545:                for (int i = 0; i < args.length; i++) {
1546:                    args[i].callMethod(getRuntime().getCurrentContext(),
1547:                            "extend_object", this );
1548:                    args[i].callMethod(getRuntime().getCurrentContext(),
1549:                            "extended", this );
1550:                }
1551:                return this ;
1552:            }
1553:
1554:            public IRubyObject inherited(IRubyObject arg, Block block) {
1555:                return getRuntime().getNil();
1556:            }
1557:
1558:            public IRubyObject initialize(IRubyObject[] args, Block block) {
1559:                Arity.checkArgumentCount(getRuntime(), args, 0, 0);
1560:                return getRuntime().getNil();
1561:            }
1562:
1563:            /**
1564:             * send( aSymbol  [, args  ]*   ) -> anObject
1565:             *
1566:             * Invokes the method identified by aSymbol, passing it any arguments
1567:             * specified. You can use __send__ if the name send clashes with an
1568:             * existing method in this object.
1569:             *
1570:             * <pre>
1571:             * class Klass
1572:             *   def hello(*args)
1573:             *     "Hello " + args.join(' ')
1574:             *   end
1575:             * end
1576:             *
1577:             * k = Klass.new
1578:             * k.send :hello, "gentle", "readers"
1579:             * </pre>
1580:             *
1581:             * @return the result of invoking the method identified by aSymbol.
1582:             */
1583:            public IRubyObject send(IRubyObject[] args, Block block) {
1584:                if (args.length < 1) {
1585:                    throw getRuntime().newArgumentError("no method name given");
1586:                }
1587:                String name = args[0].asSymbol();
1588:
1589:                IRubyObject[] newArgs = new IRubyObject[args.length - 1];
1590:                System.arraycopy(args, 1, newArgs, 0, newArgs.length);
1591:
1592:                return callMethod(getRuntime().getCurrentContext(), name,
1593:                        newArgs, CallType.FUNCTIONAL, block);
1594:            }
1595:
1596:            public IRubyObject nil_p() {
1597:                return getRuntime().getFalse();
1598:            }
1599:
1600:            public IRubyObject match(IRubyObject arg) {
1601:                return getRuntime().getFalse();
1602:            }
1603:
1604:            public IRubyObject remove_instance_variable(IRubyObject name,
1605:                    Block block) {
1606:                String id = name.asSymbol();
1607:
1608:                if (!IdUtil.isInstanceVariable(id)) {
1609:                    throw getRuntime().newNameError(
1610:                            "wrong instance variable name " + id, id);
1611:                }
1612:                if (!isTaint() && getRuntime().getSafeLevel() >= 4) {
1613:                    throw getRuntime().newSecurityError(
1614:                            "Insecure: can't remove instance variable");
1615:                }
1616:                testFrozen("class/module");
1617:
1618:                IRubyObject variable = removeInstanceVariable(id);
1619:                if (variable != null) {
1620:                    return variable;
1621:                }
1622:
1623:                throw getRuntime().newNameError(
1624:                        "instance variable " + id + " not defined", id);
1625:            }
1626:
1627:            /**
1628:             * @see org.jruby.runtime.builtin.IRubyObject#getType()
1629:             */
1630:            public RubyClass getType() {
1631:                return type();
1632:            }
1633:
1634:            /**
1635:             * @see org.jruby.runtime.builtin.IRubyObject#dataWrapStruct()
1636:             */
1637:            public synchronized void dataWrapStruct(Object obj) {
1638:                this .dataStruct = obj;
1639:            }
1640:
1641:            /**
1642:             * @see org.jruby.runtime.builtin.IRubyObject#dataGetStruct()
1643:             */
1644:            public synchronized Object dataGetStruct() {
1645:                return dataStruct;
1646:            }
1647:
1648:            public void addFinalizer(RubyProc finalizer) {
1649:                if (this .finalizer == null) {
1650:                    this .finalizer = new Finalizer(getRuntime()
1651:                            .getObjectSpace().idOf(this ));
1652:                    getRuntime().addFinalizer(this .finalizer);
1653:                }
1654:                this .finalizer.addFinalizer(finalizer);
1655:            }
1656:
1657:            public void removeFinalizers() {
1658:                if (finalizer != null) {
1659:                    finalizer.removeFinalizers();
1660:                    finalizer = null;
1661:                    getRuntime().removeFinalizer(this.finalizer);
1662:                }
1663:            }
1664:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.