Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    **** BEGIN LICENSE BLOCK *****
    * Version: EPL 1.0/GPL 2.0/LGPL 2.1
    *
    * The contents of this file are subject to the Eclipse Public
    * License Version 1.0 (the "License"); you may not use this file
    * except in compliance with the License. You may obtain a copy of
    * the License at http://www.eclipse.org/legal/epl-v10.html
    *
   * Software distributed under the License is distributed on an "AS
   * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
   * implied. See the License for the specific language governing
   * rights and limitations under the License.
   *
   * Copyright (C) 2001 Chad Fowler <chadfowler@chadfowler.com>
   * Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
   * Copyright (C) 2001-2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
   * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
   * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
   * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
   * Copyright (C) 2004-2005 Charles O Nutter <headius@headius.com>
   * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
   * Copyright (C) 2006-2007 Miguel Covarrubias <mlcovarrubias@gmail.com>
   * Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
   *
   * Alternatively, the contents of this file may be used under the terms of
   * either of the GNU General Public License Version 2 or later (the "GPL"),
   * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   * in which case the provisions of the GPL or the LGPL are applicable instead
   * of those above. If you wish to allow use of your version of this file only
   * under the terms of either the GPL or the LGPL, and not to allow others to
   * use your version of this file under the terms of the EPL, indicate your
   * decision by deleting the provisions above and replace them with the notice
   * and other provisions required by the GPL or the LGPL. If you do not delete
   * the provisions above, a recipient may use your version of this file under
   * the terms of any one of the EPL, the GPL or the LGPL.
   ***** END LICENSE BLOCK *****/
  package org.jruby;
  
  
  import static org.jruby.anno.FrameField.VISIBILITY;
  import static org.jruby.runtime.Visibility.*;
  import static org.jruby.CompatVersion.*;
  
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
 
 import java.util.Map;
 import java.util.Set;
 
 import static org.jruby.anno.FrameField.VISIBILITY;
 import static org.jruby.runtime.Visibility.*;


Author(s):
jpetersen
 
 @JRubyClass(name="Module")
 public class RubyModule extends RubyObject {
 
     private static final Logger LOG = LoggerFactory.getLogger("RubyModule");
 
     private static final boolean DEBUG = false;
     protected static final String ERR_INSECURE_SET_CONSTANT  = "Insecure: can't modify constant";
     protected static final String ERR_FROZEN_CONST_TYPE = "class/module ";
     public static final Set<StringSCOPE_CAPTURING_METHODS = new HashSet<String>(Arrays.asList(
             "eval",
             "module_eval",
             "class_eval",
             "instance_eval",
             "module_exec",
             "class_exec",
             "instance_exec",
             "binding",
             "local_variables"
             ));
 
     public static final ObjectAllocator MODULE_ALLOCATOR = new ObjectAllocator() {
         @Override
         public IRubyObject allocate(Ruby runtimeRubyClass klass) {
             return new RubyModule(runtimeklass);
         }
     };
 
     public static RubyClass createModuleClass(Ruby runtimeRubyClass moduleClass) {
         moduleClass.index = .;
         moduleClass.setReifiedClass(RubyModule.class);
         moduleClass.kindOf = new RubyModule.JavaClassKindOf(RubyModule.class);
 
         moduleClass.defineAnnotatedMethods(RubyModule.class);
         moduleClass.defineAnnotatedMethods(ModuleKernelMethods.class);
 
         return moduleClass;
     }
 
     public void checkValidBindTargetFrom(ThreadContext contextRubyModule originModulethrows RaiseException {
         if (!this.hasModuleInHierarchy(originModule)) {
             if (originModule instanceof MetaClass) {
                 throw context.runtime.newTypeError("can't bind singleton method to a different class");
             } else {
                 throw context.runtime.newTypeError("bind argument must be an instance of " + originModule.getName());
             }
         }
     }
 
     public static class ModuleKernelMethods {
         @JRubyMethod
         public static IRubyObject autoload(IRubyObject recvIRubyObject arg0IRubyObject arg1) {
             return RubyKernel.autoload(recvarg0arg1);
         }
 
         @JRubyMethod(name = "autoload?")
         public static IRubyObject autoload_p(ThreadContext contextIRubyObject recvIRubyObject arg0) {
             return RubyKernel.autoload_p(contextrecvarg0);
         }
     }
 
     @Override
     public int getNativeTypeIndex() {
         return .;
     }
 
     @Override
     public boolean isModule() {
         return true;
     }
 
     @Override
     public boolean isClass() {
         return false;
     }
 
     public boolean isSingleton() {
         return false;
     }
 
     public static class KindOf {
         public static final KindOf DEFAULT_KIND_OF = new KindOf();
         public boolean isKindOf(IRubyObject objRubyModule type) {
             return obj.getMetaClass().hasModuleInHierarchy(type);
         }
     }
 
     public static final class JavaClassKindOf extends RubyModule.KindOf {
         private final Class klass;
 
         public JavaClassKindOf(Class klass) {
             this. = klass;
         }
 
         @Override
         public boolean isKindOf(IRubyObject objRubyModule type) {
             return .isInstance(obj);
         }
     }
 
     public boolean isInstance(IRubyObject object) {
         return .isKindOf(objectthis);
     }
 
     public Map<StringConstantEntrygetConstantMap() {
         return ;
     }
 
     public synchronized Map<StringConstantEntrygetConstantMapForWrite() {
         return  == . ?  = new ConcurrentHashMap<StringConstantEntry>(4, 0.9f, 1) : ;
     }

    
AutoloadMap must be accessed after checking ConstantMap. Checking UNDEF value in constantMap works as a guard. For looking up constant, check constantMap first then try to get an Autoload object from autoloadMap. For setting constant, update constantMap first and remove an Autoload object from autoloadMap.
 
     private Map<StringAutoloadgetAutoloadMap() {
         return ;
     }
 
     private synchronized Map<StringAutoloadgetAutoloadMapForWrite() {
         return  == . ?  = new ConcurrentHashMap<StringAutoload>(4, 0.9f, 1) : ;
     }
 
     public void addIncludingHierarchy(IncludedModuleWrapper hierarchy) {
         synchronized (getRuntime().getHierarchyLock()) {
             Set<RubyClassoldIncludingHierarchies = ;
             if (oldIncludingHierarchies == . = oldIncludingHierarchies = new WeakHashSet(4);
             oldIncludingHierarchies.add(hierarchy);
         }
     }

    
separate path for MetaClass construction
 
     protected RubyModule(Ruby runtimeRubyClass metaClassboolean objectSpace) {
         super(runtimemetaClassobjectSpace);
          = runtime.allocModuleId();
         runtime.addModule(this);
         // if (parent == null) parent = runtime.getObject();
         setFlag(, !isClass());
          =  = runtime.getNextModuleGeneration();
 
         if (runtime.getInstanceConfig().isProfiling()) {
              = new ProfilingCacheEntryFactory(runtime);
         } else {
              = ;
         }
 
         // set up an invalidator for use in new optimization strategies
          = OptoFactory.newMethodInvalidator(this);
     }

    
used by MODULE_ALLOCATOR and RubyClass constructors
 
     protected RubyModule(Ruby runtimeRubyClass metaClass) {
         this(runtimemetaClassruntime.isObjectSpaceEnabled());
     }

    
standard path for Module construction
 
     protected RubyModule(Ruby runtime) {
         this(runtimeruntime.getModule());
     }
 
     public boolean needsImplementer() {
         return getFlag();
     }

    
rb_module_new
 
     public static RubyModule newModule(Ruby runtime) {
         return new RubyModule(runtime);
     }

    
rb_module_new/rb_define_module_id/rb_name_class/rb_set_class_path
 
     public static RubyModule newModule(Ruby runtimeString nameRubyModule parentboolean setParent) {
         RubyModule module = newModule(runtime);
         module.setBaseName(name);
         if (setParentmodule.setParent(parent);
         parent.setConstant(namemodule);
         return module;
     }
 
     // synchronized method per JRUBY-1173 (unsafe Double-Checked Locking)
     // FIXME: synchronization is still wrong in CP code
     public synchronized void addClassProvider(ClassProvider provider) {
         if (!.contains(provider)) {
             Set<ClassProvidercp = new HashSet<ClassProvider>();
             cp.add(provider);
              = cp;
         }
     }
 
     public synchronized void removeClassProvider(ClassProvider provider) {
         Set<ClassProvidercp = new HashSet<ClassProvider>();
         cp.remove(provider);
          = cp;
     }
 
     private void checkForCyclicInclude(RubyModule mthrows RaiseException {
         if (getNonIncludedClass() == m.getNonIncludedClass()) {
             throw getRuntime().newArgumentError("cyclic include detected");
         }
     }
 
     private RubyClass searchProvidersForClass(String nameRubyClass superClazz) {
         RubyClass clazz;
         for (ClassProvider classProvider) {
             if ((clazz = classProvider.defineClassUnder(thisnamesuperClazz)) != null) {
                 return clazz;
             }
         }
         return null;
     }
 
     private RubyModule searchProvidersForModule(String name) {
         RubyModule module;
         for (ClassProvider classProvider) {
             if ((module = classProvider.defineModuleUnder(thisname)) != null) {
                 return module;
             }
         }
         return null;
     }

    
Getter for property superClass.

Returns:
Value of property superClass.
 
     public RubyClass getSuperClass() {
         return ;
     }
 
     public void setSuperClass(RubyClass superClass) {
         // update superclass reference
         this. = superClass;
         if (superClass != null && superClass.isSynchronized()) becomeSynchronized();
     }
 
     public RubyModule getParent() {
         return ;
     }
 
     public void setParent(RubyModule parent) {
         this. = parent;
     }
 
     public Map<StringDynamicMethodgetMethods() {
         return this.;
     }
 
     public synchronized Map<StringDynamicMethodgetMethodsForWrite() {
         Map<StringDynamicMethodmyMethods = this.;
         return myMethods == . ?
             this. = new ConcurrentHashMap<StringDynamicMethod>(0, 0.9f, 1) :
             myMethods;
     }
 
     // note that addMethod now does its own put, so any change made to
     // functionality here should be made there as well
     private void putMethod(String nameDynamicMethod method) {
         getMethodsForWrite().put(namemethod);
 
         getRuntime().addProfiledMethod(namemethod);
     }

    
Is this module one that in an included one (e.g. an IncludedModuleWrapper).
 
     public boolean isIncluded() {
         return false;
     }
 
     public RubyModule getNonIncludedClass() {
         return this;
     }

    
Get the base name of this class, or null if it is an anonymous class.

Returns:
base name of the class
 
     public String getBaseName() {
         return ;
     }

    
Set the base name of the class. If null, the class effectively becomes anonymous (though constants elsewhere may reference it).

Parameters:
name the new base name of the class
 
     public void setBaseName(String name) {
          = name;
          = null;
     }

    
Generate a fully-qualified class name or a #-style name for anonymous and singleton classes. Ruby C equivalent = "classname"

Returns:
The generated class name
 
     public String getName() {
         if ( != nullreturn ;
         return calculateName();
     }

    
Get the "simple" name for the class, which is either the "base" name or the "anonymous" class name.

Returns:
the "simple" name of the class
 
     public String getSimpleName() {
         if ( != nullreturn ;
         return calculateAnonymousName();
     }

    
Recalculate the fully-qualified name of this class/module.
 
     private String calculateName() {
         boolean cache = true;
 
         if (getBaseName() == null) {
             // we are anonymous, use anonymous name
             return calculateAnonymousName();
         }
 
         Ruby runtime = getRuntime();
 
         String name = getBaseName();
         RubyClass objectClass = runtime.getObject();
 
         // First, we count the parents
         int parentCount = 0;
         for (RubyModule p = getParent() ; p != null && p != objectClass ; p = p.getParent()) {
             // Break out of cyclic namespaces like C::A = C2; C2::A = C (jruby/jruby#2314)
             if (p == thisbreak;
 
             parentCount++;
         }
 
         // Allocate a String array for all of their names and populate it
         String[] parentNames = new String[parentCount];
         int i = parentCount - 1;
         int totalLength = name.length() + parentCount * 2; // name length + enough :: for all parents
         for (RubyModule p = getParent() ; p != null && p != objectClass ; p = p.getParent(), i--) {
             // Break out of cyclic namespaces like C::A = C2; C2::A = C (jruby/jruby#2314)
             if (p == thisbreak;
 
             String pName = p.getBaseName();
 
             // This is needed when the enclosing class or module is a singleton.
             // In that case, we generated a name such as null::Foo, which broke
             // Marshalling, among others. The correct thing to do in this situation
             // is to insert the generate the name of form #<Class:01xasdfasd> if
             // it's a singleton module/class, which this code accomplishes.
             if(pName == null) {
                 cache = false;
                 pName = p.getName();
              }
 
             parentNames[i] = pName;
             totalLength += pName.length();
         }
 
         // Then build from the front using a StringBuilder
         StringBuilder builder = new StringBuilder(totalLength);
         for (String parentName : parentNames) {
             builder.append(parentName).append("::");
         }
         builder.append(name);
 
         String fullName = builder.toString();
 
         if (cache = fullName;
 
         return fullName;
     }
 
     private String calculateAnonymousName() {
         if ( == null) {
             // anonymous classes get the #<Class:0xdeadbeef> format
             StringBuilder anonBase = new StringBuilder("#<" + .getRealClass().getName() + ":0x");
             anonBase.append(Integer.toHexString(System.identityHashCode(this))).append('>');
              = anonBase.toString();
         }
         return ;
     }

    
Create a wrapper to use for including the specified module into this one. Ruby C equivalent = "include_class_new"

Returns:
The module wrapper
 
     @Deprecated
     public IncludedModuleWrapper newIncludeClass(RubyClass superClazz) {
         IncludedModuleWrapper includedModule = new IncludedModuleWrapper(getRuntime(), superClazzthis);
 
         // include its parent (and in turn that module's parents)
         if (getSuperClass() != null) {
             includedModule.includeModule(getSuperClass());
         }
 
         return includedModule;
     }
    
Finds a class that is within the current module (or class).

Parameters:
name to be found in this module (or class)
Returns:
the class or null if no such class
 
     public RubyClass getClass(String name) {
         IRubyObject module;
         if ((module = getConstantAt(name)) instanceof RubyClass) {
             return (RubyClass)module;
         }
         return null;
     }
 
     @Deprecated
     public RubyClass fastGetClass(String internedName) {
         return getClass(internedName);
     }

    
Include a new module in this module or class.

Parameters:
arg The module to include
 
     public synchronized void includeModule(IRubyObject arg) {
         assert arg != null;
 
         testFrozen("module");
 
         if (!(arg instanceof RubyModule)) {
             throw getRuntime().newTypeError("Wrong argument type " + arg.getMetaClass().getName() +
                     " (expected Module).");
         }
 
         RubyModule module = (RubyModulearg;
 
         // Make sure the module we include does not already exist
         checkForCyclicInclude(module);
 
         infectBy(module);
 
         doIncludeModule(module);
         invalidateCoreClasses();
         invalidateCacheDescendants();
     }
 
     public void defineAnnotatedMethod(Class clazzString name) {
         // FIXME: This is probably not very efficient, since it loads all methods for each call
         boolean foundMethod = false;
         for (Method method : clazz.getDeclaredMethods()) {
             if (method.getName().equals(name) && defineAnnotatedMethod(method, MethodFactory.createFactory(getRuntime().getJRubyClassLoader()))) {
                 foundMethod = true;
             }
         }
 
         if (!foundMethod) {
             throw new RuntimeException("No JRubyMethod present for method " + name + "on class " + clazz.getName());
         }
     }
 
     public void defineAnnotatedConstants(Class clazz) {
         Field[] declaredFields = clazz.getDeclaredFields();
         for (Field field : declaredFields) {
             if (Modifier.isStatic(field.getModifiers())) {
                 defineAnnotatedConstant(field);
             }
         }
     }
 
     public boolean defineAnnotatedConstant(Field field) {
         JRubyConstant jrubyConstant = field.getAnnotation(JRubyConstant.class);
 
         if (jrubyConstant == nullreturn false;
 
         String[] names = jrubyConstant.value();
         if(names.length == 0) {
             names = new String[]{field.getName()};
         }
 
         Class tp = field.getType();
         IRubyObject realVal;
 
         try {
             if(tp == Integer.class || tp == . || tp == Short.class || tp == . || tp == Byte.class || tp == .) {
                 realVal = RubyNumeric.int2fix(getRuntime(), field.getInt(null));
             } else if(tp == Boolean.class || tp == .) {
                 realVal = field.getBoolean(null) ? getRuntime().getTrue() : getRuntime().getFalse();
             } else {
                 realVal = getRuntime().getNil();
             }
         } catch(Exception e) {
             realVal = getRuntime().getNil();
         }
 
 
         for(String name : names) {
             this.setConstant(namerealVal);
         }
 
         return true;
     }
 
     @Extension
     public void defineAnnotatedMethods(Class clazz) {
         defineAnnotatedMethodsIndividually(clazz);
     }
 
     public static class MethodClumper {
 
         public void clump(Class cls) {
             Method[] declaredMethods = cls.getDeclaredMethods();
             for (Method methoddeclaredMethods) {
                 JRubyMethod anno = method.getAnnotation(JRubyMethod.class);
                 if (anno == nullcontinue;
 
                 // skip bridge methods, as generated by JDK8 javac for return-value overloaded methods
                 if (method.isBridge()) continue;
 
                 JavaMethodDescriptor desc = new JavaMethodDescriptor(method);
 
                 String name = anno.name().length == 0 ? method.getName() : anno.name()[0];
 
                 List<JavaMethodDescriptormethodDescs;
                 Map<StringList<JavaMethodDescriptor>> methodsHash = null;
                 if (desc.isStatic) {
                     if (anno.compat() == ) {
                         methodsHash = ;
                     } else if (anno.compat() == ) {
                         methodsHash = ;
                     } else if (anno.compat() == ) {
                         methodsHash = ;
                     } else {
                         methodsHash = ;
                     }
                 } else {
                     if (anno.compat() == ) {
                         methodsHash = ;
                     } else if (anno.compat() == ) {
                         methodsHash = ;
                     } else if (anno.compat() == ) {
                         methodsHash = ;
                     } else {
                         methodsHash = ;
                     }
                 }
 
                 // add to specific
                 methodDescs = methodsHash.get(name);
                 if (methodDescs == null) {
                     methodDescs = new ArrayList<JavaMethodDescriptor>();
                     methodsHash.put(namemethodDescs);
                 }
 
                 methodDescs.add(desc);
 
                 // add to general
                 methodDescs = .get(name);
                 if (methodDescs == null) {
                     methodDescs = new ArrayList<JavaMethodDescriptor>();
                     .put(namemethodDescs);
                 }
 
                 methodDescs.add(desc);
             }
         }
 
         public Map<StringList<JavaMethodDescriptor>> getAllAnnotatedMethods() {
             return ;
         }
 
         public Map<StringList<JavaMethodDescriptor>> getAnnotatedMethods() {
             return ;
         }
 
         public Map<StringList<JavaMethodDescriptor>> getAnnotatedMethods1_8() {
             return ;
         }
 
         public Map<StringList<JavaMethodDescriptor>> getAnnotatedMethods1_9() {
             return ;
         }
 
         public Map<StringList<JavaMethodDescriptor>> getAnnotatedMethods2_0() {
             return ;
         }
 
             return ;
         }
 
             return ;
         }
 
             return ;
         }
 
             return ;
         }
     }
 
     public void defineAnnotatedMethodsIndividually(Class clazz) {
         TypePopulator populator;
 
             // we want reflected invokers or need full traces, use default (slow) populator
             if (.info("trace mode, using default populator");
             populator = .;
         } else {
             try {
                 String qualifiedName = "org.jruby.gen." + clazz.getCanonicalName().replace('.''$');
 
                 if (.info("looking for " + qualifiedName + .);
 
                 Class populatorClass = Class.forName(qualifiedName + .);
                 populator = (TypePopulator)populatorClass.newInstance();
             } catch (Throwable t) {
                 if (.info("Could not find it, using default populator");
                 populator = .;
             }
         }
 
         populator.populate(thisclazz);
     }
 
     public boolean defineAnnotatedMethod(String nameList<JavaMethodDescriptormethodsMethodFactory methodFactory) {
         JavaMethodDescriptor desc = methods.get(0);
         if (methods.size() == 1) {
             return defineAnnotatedMethod(namedescmethodFactory);
         } else {
             CompatVersion compatVersion = getRuntime().getInstanceConfig().getCompatVersion();
             if (shouldBindMethod(compatVersiondesc.anno.compat())) {
                 DynamicMethod dynamicMethod = methodFactory.getAnnotatedMethod(thismethods);
                 define(thisdescnamedynamicMethod);
 
                 return true;
             }
 
             return false;
         }
     }
 
     public boolean defineAnnotatedMethod(Method methodMethodFactory methodFactory) {
         JRubyMethod jrubyMethod = method.getAnnotation(JRubyMethod.class);
 
         if (jrubyMethod == nullreturn false;
 
         CompatVersion compatVersion = getRuntime().getInstanceConfig().getCompatVersion();
         if (shouldBindMethod(compatVersionjrubyMethod.compat())) {
             JavaMethodDescriptor desc = new JavaMethodDescriptor(method);
             DynamicMethod dynamicMethod = methodFactory.getAnnotatedMethod(thisdesc);
             define(thisdescmethod.getName(), dynamicMethod);
 
             return true;
         }
         return false;
     }
 
     public boolean defineAnnotatedMethod(String nameJavaMethodDescriptor descMethodFactory methodFactory) {
         JRubyMethod jrubyMethod = desc.anno;
 
         if (jrubyMethod == nullreturn false;
 
         CompatVersion compatVersion = getRuntime().getInstanceConfig().getCompatVersion();
         if (shouldBindMethod(compatVersionjrubyMethod.compat())) {
             DynamicMethod dynamicMethod = methodFactory.getAnnotatedMethod(thisdesc);
             define(thisdescnamedynamicMethod);
 
             return true;
         }
         return false;
     }
 
     public void undefineMethod(String name) {
         addMethod(name, UndefinedMethod.getInstance());
     }

    
rb_undef
 
     public void undef(ThreadContext contextString name) {
         Ruby runtime = context.runtime;
 
         testFrozen("module");
         if (name.equals("__id__") || name.equals("__send__")) {
             runtime.getWarnings().warn(."undefining `"name +"' may cause serious problem");
         }
         DynamicMethod method = searchMethod(name);
         if (method.isUndefined()) {
             String s0 = " class";
             RubyModule c = this;
 
             if (c.isSingleton()) {
                 IRubyObject obj = ((MetaClass)c).getAttached();
 
                 if (obj != null && obj instanceof RubyModule) {
                     c = (RubyModuleobj;
                     s0 = "";
                 }
             } else if (c.isModule()) {
                 s0 = " module";
             }
 
             throw runtime.newNameError("Undefined method " + name + " for" + s0 + " '" + c.getName() + "'"name);
         }
         addMethod(name, UndefinedMethod.getInstance());
 
         if (isSingleton()) {
             IRubyObject singleton = ((MetaClass)this).getAttached();
             singleton.callMethod(context"singleton_method_undefined"runtime.newSymbol(name));
         } else {
             callMethod(context"method_undefined"runtime.newSymbol(name));
         }
     }
 
     @JRubyMethod(name = "include?", required = 1)
     public IRubyObject include_p(ThreadContext contextIRubyObject arg) {
         if (!arg.isModule()) {
             throw context.runtime.newTypeError(argcontext.runtime.getModule());
         }
         RubyModule moduleToCompare = (RubyModulearg;
 
         // See if module is in chain...Cannot match against itself so start at superClass.
         for (RubyModule p = getSuperClass(); p != nullp = p.getSuperClass()) {
             if (p.isSame(moduleToCompare)) {
                 return context.runtime.getTrue();
             }
         }
 
         return context.runtime.getFalse();
     }
 
     // TODO: Consider a better way of synchronizing
     public void addMethod(String nameDynamicMethod method) {
         testFrozen("class/module");
 
         addMethodInternal(namemethod);
     }
 
     public void addMethodInternal(String nameDynamicMethod method) {
         synchronized(getMethodsForWrite()) {
             addMethodAtBootTimeOnly(namemethod);
             invalidateCoreClasses();
             invalidateCacheDescendants();
         }
     }

    
This method is not intended for use by normal users; it is a fast-path method that skips synchronization and hierarchy invalidation to speed boot-time method definition.

Parameters:
name The name to which to bind the method
method The method to bind
 
     public void addMethodAtBootTimeOnly(String nameDynamicMethod method) {
         getMethodsForWrite().put(namemethod);
 
         getRuntime().addProfiledMethod(namemethod);
     }
 
     public void removeMethod(ThreadContext contextString name) {
         Ruby runtime = context.runtime;
 
         testFrozen("class/module");
 
         // We can safely reference methods here instead of doing getMethods() since if we
         // are adding we are not using a IncludedModuleWrapper.
         synchronized(getMethodsForWrite()) {
             DynamicMethod method = (DynamicMethodgetMethodsForWrite().remove(name);
             if (method == null) {
                 throw runtime.newNameError("method '" + name + "' not defined in " + getName(), name);
             }
 
             invalidateCoreClasses();
             invalidateCacheDescendants();
         }
 
         if (isSingleton()) {
             IRubyObject singleton = ((MetaClass)this).getAttached();
             singleton.callMethod(context"singleton_method_removed"runtime.newSymbol(name));
         } else {
             callMethod(context"method_removed"runtime.newSymbol(name));
         }
     }

    
Search through this module and supermodules for method definitions. Cache superclass definitions in this class.

Parameters:
name The name of the method to search for
Returns:
The method, or UndefinedMethod if not found
 
     public DynamicMethod searchMethod(String name) {
         return searchWithCache(name).;
     }

    
Search through this module and supermodules for method definitions. Cache superclass definitions in this class.

Parameters:
name The name of the method to search for
Returns:
The method, or UndefinedMethod if not found
 
     public CacheEntry searchWithCache(String name) {
         CacheEntry entry = cacheHit(name);
 
         if (entry != nullreturn entry;
 
         // we grab serial number first; the worst that will happen is we cache a later
         // update with an earlier serial number, which would just flush anyway
         int token = getGeneration();
         DynamicMethod method = searchMethodInner(name);
 
         if (method instanceof CacheableMethod) {
             method = ((CacheableMethodmethod).getMethodForCaching();
         }
 
         return method != null ? addToCache(namemethodtoken) : addToCache(name, UndefinedMethod.getInstance(), token);
     }
 
     @Deprecated
     public final int getCacheToken() {
         return ;
     }
 
     public final int getGeneration() {
         return ;
     }
 
     public final Integer getGenerationObject() {
         return ;
    }
    private final Map<StringCacheEntrygetCachedMethods() {
        return this.;
    }
    private final Map<StringCacheEntrygetCachedMethodsForWrite() {
        Map<StringCacheEntrymyCachedMethods = this.;
        return myCachedMethods == . ?
            this. = new ConcurrentHashMap<StringCacheEntry>(0, 0.75f, 1) :
            myCachedMethods;
    }
    private CacheEntry cacheHit(String name) {
        CacheEntry cacheEntry = getCachedMethods().get(name);
        if (cacheEntry != null) {
            if (cacheEntry.token == getGeneration()) {
                return cacheEntry;
            }
        }
        return null;
    }
    {
        for (RubyModule mod : gatherModules(module)) {
            for (String key : mod.getConstantMap().keySet()) {
                invalidateConstantCache(key);
            }
        }
    }
    protected static abstract class CacheEntryFactory {
        public abstract CacheEntry newCacheEntry(String name,DynamicMethod methodint token);

        
Test all WrapperCacheEntryFactory instances in the chain for assignability from the given class.

Parameters:
cacheEntryFactoryClass the class from which to test assignability
Returns:
whether the given class is assignable from any factory in the chain
        public boolean hasCacheEntryFactory(Class cacheEntryFactoryClass) {
            CacheEntryFactory current = this;
            while (current instanceof WrapperCacheEntryFactory) {
                if (cacheEntryFactoryClass.isAssignableFrom(current.getClass())) {
                    return true;
                }
                current = ((WrapperCacheEntryFactory)current).getPrevious();
            }
            return cacheEntryFactoryClass.isAssignableFrom(current.getClass());
        }
    }

    
A wrapper CacheEntryFactory, for delegating cache entry creation along a chain.
    protected static abstract class WrapperCacheEntryFactory extends CacheEntryFactory {
        
The CacheEntryFactory being wrapped.
        protected final CacheEntryFactory previous;

        
Construct a new WrapperCacheEntryFactory using the given CacheEntryFactory as the "previous" wrapped factory.

Parameters:
previous the wrapped factory
        public WrapperCacheEntryFactory(CacheEntryFactory previous) {
            this. = previous;
        }
        public CacheEntryFactory getPrevious() {
            return ;
        }
    }
    protected static final CacheEntryFactory NormalCacheEntryFactory = new CacheEntryFactory() {
        @Override
        public CacheEntry newCacheEntry(String nameDynamicMethod methodint token) {
            return new CacheEntry(methodtoken);
        }
    };
    protected static class SynchronizedCacheEntryFactory extends WrapperCacheEntryFactory {
        public SynchronizedCacheEntryFactory(CacheEntryFactory previous) {
            super(previous);
        }
        @Override
        public CacheEntry newCacheEntry(String name,DynamicMethod methodint token) {
            if (method.isUndefined()) {
                return new CacheEntry(methodtoken);
            }
            // delegate up the chain
            CacheEntry delegated = .newCacheEntry(name,methodtoken);
            return new CacheEntry(new SynchronizedDynamicMethod(delegated.method), delegated.token);
        }
    }
    protected static class ProfilingCacheEntryFactory extends WrapperCacheEntryFactory {
        private final MethodEnhancer enhancer;
        public ProfilingCacheEntryFactoryRuby runtimeCacheEntryFactory previous) {
            super(previous);
            this. = runtime.getProfilingService().newMethodEnhancerruntime );
        }
        private MethodEnhancer getMethodEnhancer() {
            return ;
        }
        @Override
        public CacheEntry newCacheEntry(String nameDynamicMethod methodint token) {
            if (method.isUndefined()) {
                return new CacheEntry(methodtoken);
            }
            CacheEntry delegated = .newCacheEntry(namemethodtoken);