Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   ***** BEGIN LICENSE BLOCK *****
   * Version: CPL 1.0/GPL 2.0/LGPL 2.1
   *
   * The contents of this file are subject to the Common 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/cpl-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 Alan Moore <alan_moore@gmx.net>
  * 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 Joey Gibson <joey@joeygibson.com>
  * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
  * Copyright (C) 2006 Derek Berner <derek.berner@state.nm.us>
  * Copyright (C) 2006 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 CPL, 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 CPL, the GPL or the LGPL.
  ***** END LICENSE BLOCK *****/
 package org.jruby;
 
 import static org.jruby.util.StringSupport.codeLength;
 import static org.jruby.util.StringSupport.codePoint;
 
 
Represents a Ruby symbol (e.g. :bar)
 
 @JRubyClass(name="Symbol")
 public class RubySymbol extends RubyObject {
     private final String symbol;
     private final int id;
     private final ByteList symbolBytes;
    
    

Parameters:
runtime
internedSymbol the String value of the new Symbol. This must have been previously interned
 
     private RubySymbol(Ruby runtimeString internedSymbolByteList symbolBytes) {
         super(runtimeruntime.getSymbol(), false);
         // symbol string *must* be interned
 
         //        assert internedSymbol == internedSymbol.intern() : internedSymbol + " is not interned";
 
         if (!runtime.is1_9()) {
             int length = symbolBytes.getBegin() + symbolBytes.getRealSize();
             for (int i = symbolBytes.getBegin(); i < lengthi++) {
                 if (symbolBytes.getUnsafeBytes()[i] == 0) {
                     throw runtime.newSyntaxError("symbol cannot contain '\\0'");
                 }
             }
         }
 
         this. = internedSymbol;
        this. = symbolBytes;
        this. = runtime.allocSymbolId();
    }
    private RubySymbol(Ruby runtimeString internedSymbol) {
        this(runtimeinternedSymbolsymbolBytesFromString(runtimeinternedSymbol));
    }
    public static RubyClass createSymbolClass(Ruby runtime) {
        RubyClass symbolClass = runtime.defineClass("Symbol"runtime.getObject(), .);
        runtime.setSymbol(symbolClass);
        RubyClass symbolMetaClass = symbolClass.getMetaClass();
        symbolClass.index = .;
        symbolClass.setReifiedClass(RubySymbol.class);
        symbolClass.kindOf = new RubyModule.KindOf() {
            @Override
            public boolean isKindOf(IRubyObject objRubyModule type) {
                return obj instanceof RubySymbol;
            }
        };
        symbolClass.defineAnnotatedMethods(RubySymbol.class);
        symbolMetaClass.undefineMethod("new");
        
        return symbolClass;
    }
    
    @Override
    public int getNativeTypeIndex() {
        return .;
    }

    
rb_to_id

Returns:
a String representation of the symbol
    @Override
    public String asJavaString() {
        return ;
    }
    @Override
    public String toString() {
        return ;
    }
    final ByteList getBytes() {
        return ;
    }

    
short circuit for Symbol key comparison
    @Override
    public final boolean eql(IRubyObject other) {
        return other == this;
    }
    @Override
    public boolean isImmediate() {
    	return true;
    }
    @Override
    public RubyClass getSingletonClass() {
        throw getRuntime().newTypeError("can't define singleton");
    }
    public static RubySymbol getSymbolLong(Ruby runtimelong id) {
        return runtime.getSymbolTable().lookup(id);
    }
    /* Symbol class methods.
     * 
     */
    public static RubySymbol newSymbol(Ruby runtimeString name) {
        return runtime.getSymbolTable().getSymbol(name);
    }
    @Deprecated
    public RubyFixnum to_i() {
        return to_i(getRuntime());
    }
    @JRubyMethod(name = "to_i", compat = .)
    public RubyFixnum to_i(ThreadContext context) {
        return to_i(context.runtime);
    }
    private final RubyFixnum to_i(Ruby runtime) {
        return runtime.newFixnum();
    }
    @Deprecated
    public RubyFixnum to_int() {
        return to_int(getRuntime());
    }
    @JRubyMethod(name = "to_int", compat = .)
    public RubyFixnum to_int(ThreadContext context) {
        return to_int(context.runtime);
    }
    private final RubyFixnum to_int(Ruby runtime) {
        if (runtime.isVerbose()) runtime.getWarnings().warn(."treating Symbol as an integer");
        return to_i(runtime);
    }
    @Deprecated
    @Override
    public IRubyObject inspect() {
        return inspect(getRuntime());
    }
    @JRubyMethod(name = "inspect", compat = .)
    public IRubyObject inspect(ThreadContext context) {
        return inspect(context.runtime);
    }
    private final IRubyObject inspect(Ruby runtime) {
        final ByteList bytes = isSymbolName() ?  : 
                ((RubyString)RubyString.newString(runtime).dump()).getByteList();
        ByteList result = new ByteList(bytes.getRealSize() + 1);
        result.append((byte)':').append(bytes);
        return RubyString.newString(runtimeresult);
    }
    @Deprecated
    public IRubyObject inspect19() {
        return inspect19(getRuntime());
    }
    @JRubyMethod(name = "inspect", compat = .)
    public IRubyObject inspect19(ThreadContext context) {
        return inspect19(context.runtime);
    }
    private final IRubyObject inspect19(Ruby runtime) {
        ByteList result = new ByteList(.getRealSize() + 1);
        result.setEncoding(.getEncoding());
        result.append((byte)':');
        result.append();
        RubyString str = RubyString.newString(runtimeresult); 
        // TODO: 1.9 rb_enc_symname_p
        if (isPrintable() && isSymbolName19()) return str;
            
        str = (RubyString)str.inspect19();
        ByteList bytes = str.getByteList();
        bytes.set(0, ':');
        bytes.set(1, '"');
        
        return str;
    }
    @Override
    public IRubyObject to_s() {
        return to_s(getRuntime());
    }
    
    @JRubyMethod(name = "to_s")
    public IRubyObject to_s(ThreadContext context) {
        return to_s(context.runtime);
    }
    
    private final IRubyObject to_s(Ruby runtime) {
        return RubyString.newStringShared(runtime);
    }
    public IRubyObject id2name() {
        return to_s(getRuntime());
    }
    
    @JRubyMethod(name = "id2name")
    public IRubyObject id2name(ThreadContext context) {
        return to_s(context);
    }
    @JRubyMethod(name = "===", required = 1)
    @Override
    public IRubyObject op_eqq(ThreadContext contextIRubyObject other) {
        return super.op_equal(contextother);
    }
    @Deprecated
    @Override
    public RubyFixnum hash() {
        return getRuntime().newFixnum(hashCode());
    }
    @JRubyMethod(name = "hash")
    public RubyFixnum hash(ThreadContext context) {
        return context.runtime.newFixnum(hashCode());
    }
    
    @Override
    public int hashCode() {
        return ;
    }
    public int getId() {
        return ;
    }
    
    @Override
    public boolean equals(Object other) {
        return other == this;
    }
    
    @JRubyMethod(name = "to_sym")
    public IRubyObject to_sym() {
        return this;
    }
    @JRubyMethod(name = "intern", compat = .)
    public IRubyObject to_sym19() {
        return this;
    }
    @Override
    public IRubyObject taint(ThreadContext context) {
        return this;
    }
    private RubyString newShared(Ruby runtime) {
        return RubyString.newStringShared(runtime);
    }
    private RubyString rubyStringFromString(Ruby runtime) {
        return RubyString.newString(runtime);
    }
    @JRubyMethod(name = {"succ""next"}, compat = .)
    public IRubyObject succ(ThreadContext context) {
        Ruby runtime = context.runtime;
        return newSymbol(runtimenewShared(runtime).succ19(context).toString());
    }
    @JRubyMethod(name = "<=>", compat = .)
    @Override
    public IRubyObject op_cmp(ThreadContext contextIRubyObject other) {
        Ruby runtime = context.runtime;
        
        return !(other instanceof RubySymbol) ? runtime.getNil() :
                newShared(runtime).op_cmp19(context, ((RubySymbol)other).newShared(runtime));
    }
    @JRubyMethod(name = "casecmp", compat = .)
    public IRubyObject casecmp(ThreadContext contextIRubyObject other) {
        Ruby runtime = context.runtime;
        
        return !(other instanceof RubySymbol) ? runtime.getNil() :
                newShared(runtime).casecmp19(context, ((RubySymbolother).newShared(runtime));
    }
    @JRubyMethod(name = {"=~""match"}, compat = .)
    @Override
    public IRubyObject op_match19(ThreadContext contextIRubyObject other) {
        return newShared(context.runtime).op_match19(contextother);
    }
    @JRubyMethod(name = {"[]""slice"}, compat = .)
    public IRubyObject op_aref(ThreadContext contextIRubyObject arg) {
        return newShared(context.runtime).op_aref19(contextarg);
    }
    @JRubyMethod(name = {"[]""slice"}, compat = .)
    public IRubyObject op_aref(ThreadContext contextIRubyObject arg1IRubyObject arg2) {
        return newShared(context.runtime).op_aref19(contextarg1arg2);
    }
    @JRubyMethod(name = {"length""size"}, compat = .)
    public IRubyObject length() {
        return newShared(getRuntime()).length19();
    }
    @JRubyMethod(name = "empty?", compat = .)
    public IRubyObject empty_p(ThreadContext context) {
        return newShared(context.runtime).empty_p(context);
    }
    @JRubyMethod(name = "upcase", compat = .)
    public IRubyObject upcase(ThreadContext context) {
        Ruby runtime = context.runtime;
        
        return newSymbol(runtimerubyStringFromString(runtime).upcase19(context).toString());
    }
    @JRubyMethod(name = "downcase", compat = .)
    public IRubyObject downcase(ThreadContext context) {
        Ruby runtime = context.runtime;
        
        return newSymbol(runtimerubyStringFromString(runtime).downcase19(context).toString());
    }
    @JRubyMethod(name = "capitalize", compat = .)
    public IRubyObject capitalize(ThreadContext context) {
        Ruby runtime = context.runtime;
        
        return newSymbol(runtimerubyStringFromString(runtime).capitalize19(context).toString());
    }
    @JRubyMethod(name = "swapcase", compat = .)
    public IRubyObject swapcase(ThreadContext context) {
        Ruby runtime = context.runtime;
        
        return newSymbol(runtimerubyStringFromString(runtime).swapcase19(context).toString());
    }
    @JRubyMethod(name = "encoding", compat = .)
    public IRubyObject encoding(ThreadContext context) {
        return context.runtime.getEncodingService().getEncoding(.getEncoding());
    }
    
    public IRubyObject to_proc(ThreadContext context) {
        StaticScope scope = context.runtime.getStaticScopeFactory().getDummyScope();
        final CallSite site = new FunctionalCachingCallSite();
        BlockBody body = new ContextAwareBlockBody(scope..) {
            private IRubyObject yieldInner(ThreadContext contextRubyArray array) {
                if (array.isEmpty()) {
                    throw context.runtime.newArgumentError("no receiver given");
                }
                IRubyObject self = array.shift(context);
                return site.call(contextselfselfarray.toJavaArray());
            }
            
            @Override
            public IRubyObject yield(ThreadContext contextIRubyObject valueBinding bindingType type) {
                return yieldInner(context, ArgsUtil.convertToRubyArray(context.runtimevaluefalse));
            }
            @Override
            public IRubyObject yield(ThreadContext contextIRubyObject valueIRubyObject selfRubyModule klassboolean aValueBinding bindingType type) {
                RubyArray array = aValue && value instanceof RubyArray ?
                        (RubyArrayvalue : ArgsUtil.convertToRubyArray(context.runtimevaluefalse);
                return yieldInner(contextarray);
            }
            @Override
            public IRubyObject yieldSpecific(ThreadContext contextIRubyObject arg0Binding bindingBlock.Type type) {
                return site.call(contextarg0arg0);
            }
            @Override
            public IRubyObject yieldSpecific(ThreadContext contextIRubyObject arg0IRubyObject arg1Binding bindingBlock.Type type) {
                return site.call(contextarg0arg0arg1);
            }
            @Override
            public IRubyObject yieldSpecific(ThreadContext contextIRubyObject arg0IRubyObject arg1IRubyObject arg2Binding bindingBlock.Type type) {
                return site.call(contextarg0arg0arg1arg2);
            }
            @Override
            public Block cloneBlock(Binding binding) {
                return new Block(thisbinding);
            }
            public String getFile() {
                return ;
            }
            public int getLine() {
                return -1;
            }
        };
        return RubyProc.newProc(context.runtime,
                                new Block(bodycontext.currentBinding()),
                                ..);
    }
    
    private static boolean isIdentStart(char c) {
        return ((c >= 'a' && c <= 'z')|| (c >= 'A' && c <= 'Z') || c == '_');
    }
    
    private static boolean isIdentChar(char c) {
        return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_');
    }
    
    private static boolean isIdentifier(String s) {
        if (s == null || s.length() <= 0 || !isIdentStart(s.charAt(0))) return false;
        for (int i = 1; i < s.length(); i++) {
            if (!isIdentChar(s.charAt(i))) return false;
        }
        
        return true;
    }
    
    
is_special_global_name from parse.c.

Parameters:
s
Returns:
    private static boolean isSpecialGlobalName(String s) {
        if (s == null || s.length() <= 0) return false;
        int length = s.length();
           
        switch (s.charAt(0)) {        
        case '~'case '*'case '$'case '?'case '!'case '@'case '/'case '\\':        
        case ';'case ','case '.'case '='case ':'case '<'case '>'case '\"':        
        case '&'case '`'case '\''case '+'case '0':
            return length == 1;            
        case '-':
            return (length == 1 || (length == 2 && isIdentChar(s.charAt(1))));
            
        default:
            for (int i = 0; i < lengthi++) {
                if (!Character.isDigit(s.charAt(i))) return false;
            }
        }
        
        return true;
    }
    private boolean isPrintable() {
        Ruby runtime = getRuntime();
        int p = .getBegin();
        int end = p + .getRealSize();
        byte[]bytes = .getUnsafeBytes();
        Encoding enc = .getEncoding();
        while (p < end) {
            int c = codePoint(runtimeencbytespend);
            
            if (!enc.isPrint(c)) return false;
            
            p += codeLength(runtimeencc);
        }
        
        return true;
    }
    private static boolean isSymbolName19(String s) {
        if (s == null || s.length() < 1) return false;
        int length = s.length();
        char c = s.charAt(0);
        
        return isSymbolNameCommon(sclength) || 
                (c == '!' && (length == 1 ||
                             (length == 2 && (s.charAt(1) == '~' || s.charAt(1) == '=')))) ||
                isSymbolLocal(sclength);
    }
    private static boolean isSymbolName(String s) {
        if (s == null || s.length() < 1) return false;
        int length = s.length();
        char c = s.charAt(0);
        
        return isSymbolNameCommon(sclength) || isSymbolLocal(sclength);
    }
    private static boolean isSymbolNameCommon(String schar cint length) {        
        switch (c) {
        case '$':
            if (length > 1 && isSpecialGlobalName(s.substring(1))) return true;
            return isIdentifier(s.substring(1));
        case '@':
            int offset = 1;
            if (length >= 2 && s.charAt(1) == '@'offset++;
            return isIdentifier(s.substring(offset));
        case '<':
            return (length == 1 || (length == 2 && (s.equals("<<") || s.equals("<="))) ||
                    (length == 3 && s.equals("<=>")));
        case '>':
            return (length == 1) || (length == 2 && (s.equals(">>") || s.equals(">=")));
        case '=':
            return ((length == 2 && (s.equals("==") || s.equals("=~"))) ||
                    (length == 3 && s.equals("===")));
        case '*':
            return (length == 1 || (length == 2 && s.equals("**")));
        case '+':
            return (length == 1 || (length == 2 && s.equals("+@")));
        case '-':
            return (length == 1 || (length == 2 && s.equals("-@")));
        case '|'case '^'case '&'case '/'case '%'case '~'case '`':
            return length == 1;
        case '[':
            return s.equals("[]") || s.equals("[]=");
        }
        return false;
    }
    private static boolean isSymbolLocal(String schar cint length) {
        if (!isIdentStart(c)) return false;
        boolean localID = (c >= 'a' && c <= 'z');
        int last = 1;
        for (; last < lengthlast++) {
            char d = s.charAt(last);
            if (!isIdentChar(d)) break;
        }
        if (last == lengthreturn true;
        if (localID && last == length - 1) {
            char d = s.charAt(last);
            return d == '!' || d == '?' || d == '=';
        }
        return false;
    }
    
    @JRubyMethod(name = "all_symbols", meta = true)
    public static IRubyObject all_symbols(ThreadContext contextIRubyObject recv) {
        return context.runtime.getSymbolTable().all_symbols();
    }
    @Deprecated
    public static IRubyObject all_symbols(IRubyObject recv) {
        return recv.getRuntime().getSymbolTable().all_symbols();
    }
    public static RubySymbol unmarshalFrom(UnmarshalStream inputthrows java.io.IOException {
        RubySymbol result = newSymbol(input.getRuntime(), RubyString.byteListToString(input.unmarshalString()));
        
        input.registerLinkTarget(result);
        
        return result;
    }
    @Override
    public Object toJava(Class target) {
        if (target == String.class || target == CharSequence.classreturn ;
        return super.toJava(target);
    }
    private static ByteList symbolBytesFromString(Ruby runtimeString internedSymbol) {
        if (runtime.is1_9()) {
            return new ByteList(ByteList.plain(internedSymbol), .false);
        } else {
            return ByteList.create(internedSymbol);
        }
    }
    public static final class SymbolTable {
        static final int DEFAULT_INITIAL_CAPACITY = 2048; // *must* be power of 2!
        static final int MAXIMUM_CAPACITY = 1 << 30;
        static final float DEFAULT_LOAD_FACTOR = 0.75f;
        
        private final ReentrantLock tableLock = new ReentrantLock();
        private volatile SymbolEntry[] symbolTable;
        private final ConcurrentHashMap<ByteListRubySymbolbytelistTable = new ConcurrentHashMap<ByteListRubySymbol>(100, 0.75f, Runtime.getRuntime().availableProcessors());
        private int size;
        private int threshold;
        private final float loadFactor;
        private final Ruby runtime;
        
        public SymbolTable(Ruby runtime) {
            this. = runtime;
            this. = ;
            this. = (int)( * );
            this. = new SymbolEntry[];
        }
        
        // note all fields are final -- rehash creates new entries when necessary.
        // as documented in java.util.concurrent.ConcurrentHashMap.java, that will
        // statistically affect only a small percentage (< 20%) of entries for a given rehash.
        static class SymbolEntry {
            final int hash;
            final String name;
            final RubySymbol symbol;
            final SymbolEntry next;
            
            SymbolEntry(int hashString nameRubySymbol symbolSymbolEntry next) {
                this. = hash;
                this. = name;
                this. = symbol;
                this. = next;
            }
        }
        public RubySymbol getSymbol(String name) {
            int hash = name.hashCode();
            SymbolEntry[] table = ;
            
            for (SymbolEntry e = getEntryFromTable(tablehash); e != nulle = e.next) {
                if (isSymbolMatch(namehashe)) return e.symbol;
            }
            
            return createSymbol(namesymbolBytesFromString(name), hashtable);
        }
        public RubySymbol getSymbol(ByteList bytes) {
            RubySymbol symbol = .get(bytes);
            if (symbol != nullreturn symbol;
            String name = bytes.toString();
            int hash = name.hashCode();
            SymbolEntry[] table = ;
            
            for (SymbolEntry e = getEntryFromTable(tablehash); e != nulle = e.next) {
                if (isSymbolMatch(namehashe)) {
                    symbol = e.symbol;
                    break;
                }
            }
            if (symbol == null) {
                symbol = createSymbol(namebyteshashtable);
            }
            
            .put(bytessymbol);
            return symbol;
        }
        public RubySymbol fastGetSymbol(String internedName) {
            SymbolEntry[] table = ;
            
            for (SymbolEntry e = getEntryFromTable(internedName.hashCode()); e != nulle = e.next) {
                if (isSymbolMatch(internedNamee)) return e.symbol;
            }
            
            return fastCreateSymbol(internedNametable);
        }
        private static SymbolEntry getEntryFromTable(SymbolEntry[] tableint hash) {
            return table[hash & (table.length - 1)];
        }
        private static boolean isSymbolMatch(String nameint hashSymbolEntry entry) {
            return hash == entry.hash && name.equals(entry.name);
        }
        private static boolean isSymbolMatch(String internedNameSymbolEntry entry) {
            return internedName == entry.name;
        }
        private RubySymbol createSymbol(String nameByteList valueint hashSymbolEntry[] table) {
            ReentrantLock lock;
            (lock = ).lock();
            try {
                int index;                
                int potentialNewSize =  + 1;
                
                table = potentialNewSize >  ? rehash() : ;
                // try lookup again under lock
                for (SymbolEntry e = table[index = hash & (table.length - 1)]; e != nulle = e.next) {
                    if (hash == e.hash && name.equals(e.name)) return e.symbol;
                }
                String internedName = name.intern();
                RubySymbol symbol = new RubySymbol(internedNamevalue);
                table[index] = new SymbolEntry(hashinternedNamesymboltable[index]);
                 = potentialNewSize;
                // write-volatile
                 = table;
                return symbol;
            } finally {
                lock.unlock();
            }
        }
        private RubySymbol fastCreateSymbol(String internedNameSymbolEntry[] table) {
            ReentrantLock lock;
            (lock = ).lock();
            try {
                int index;
                int hash;
                int potentialNewSize =  + 1;
                
                table = potentialNewSize >  ? rehash() : ;
                // try lookup again under lock
                for (SymbolEntry e = table[index = (hash = internedName.hashCode()) & (table.length - 1)]; e != nulle = e.next) {
                    if (internedName == e.namereturn e.symbol;
                }
                RubySymbol symbol = new RubySymbol(internedName);
                table[index] = new SymbolEntry(hashinternedNamesymboltable[index]);
                 = potentialNewSize;
                // write-volatile
                 = table;
                return symbol;
            } finally {
                lock.unlock();
            }
        }
        
        // backwards-compatibility, but threadsafe now
        public RubySymbol lookup(String name) {
            int hash = name.hashCode();
            SymbolEntry[] table;
            
            for (SymbolEntry e = (table = )[hash & (table.length - 1)]; e != nulle = e.next) {
                if (hash == e.hash && name.equals(e.name)) return e.symbol;
            }
            return null;
        }
        
        public RubySymbol lookup(long id) {
            SymbolEntry[] table = ;
            
            for (int i = table.length; --i >= 0; ) {
                for (SymbolEntry e = table[i]; e != nulle = e.next) {
                    if (id == e.symbol.idreturn e.symbol;
                }
            }
            return null;
        }
        
        public RubyArray all_symbols() {
            SymbolEntry[] table = this.;
            RubyArray array = .newArray(this.);
            
            for (int i = table.length; --i >= 0; ) {
                for (SymbolEntry e = table[i]; e != nulle = e.next) {
                    array.append(e.symbol);
                }
            }
            return array;
        }
        
        // not so backwards-compatible here, but no one should have been
        // calling this anyway.
        @Deprecated
        public void store(RubySymbol symbol) {
            throw new UnsupportedOperationException();
        }
        
        private SymbolEntry[] rehash() {
            SymbolEntry[] oldTable = ;
            int oldCapacity = oldTable.length;
            
            if (oldCapacity >= return oldTable;
            
            int newCapacity = oldCapacity << 1;
            SymbolEntry[] newTable = new SymbolEntry[newCapacity];
             = (int)(newCapacity * );
            int sizeMask = newCapacity - 1;
            SymbolEntry e;
            for (int i = oldCapacity; --i >= 0; ) {
                // We need to guarantee that any existing reads of old Map can
                //  proceed. So we cannot yet null out each bin.
                e = oldTable[i];
                if (e != null) {
                    SymbolEntry next = e.next;
                    int idx = e.hash & sizeMask;
                    //  Single node on list
                    if (next == null) {
                        newTable[idx] = e;
                    } else {
                        // Reuse trailing consecutive sequence at same slot
                        SymbolEntry lastRun = e;
                        int lastIdx = idx;
                        for (SymbolEntry last = next;
                             last != null;
                             last = last.next) {
                            int k = last.hash & sizeMask;
                            if (k != lastIdx) {
                                lastIdx = k;
                                lastRun = last;
                            }
                        }
                        newTable[lastIdx] = lastRun;
                        // Clone all remaining nodes
                        for (SymbolEntry p = ep != lastRunp = p.next) {
                            int k = p.hash & sizeMask;
                            SymbolEntry n = newTable[k];
                            newTable[k] = new SymbolEntry(p.hashp.namep.symboln);
                        }
                    }
                }
            }
             = newTable;
            return newTable;
        }
        
    }