1 7 package org.jruby.runtime.builtin.meta; 8 9 import java.util.HashMap ; 10 import org.jruby.Ruby; 11 import org.jruby.RubyClass; 12 import org.jruby.RubyHash; 13 import org.jruby.runtime.Arity; 14 import org.jruby.runtime.Block; 15 import org.jruby.runtime.CallbackFactory; 16 import org.jruby.runtime.ClassIndex; 17 import org.jruby.runtime.ObjectAllocator; 18 import org.jruby.runtime.builtin.IRubyObject; 19 import org.jruby.util.collections.SinglyLinkedList; 20 21 public class HashMetaClass extends ObjectMetaClass { 22 public HashMetaClass(Ruby runtime) { 23 super("Hash", RubyHash.class, runtime.getObject(), HASH_ALLOCATOR); 24 this.index = ClassIndex.HASH; 25 } 26 27 public HashMetaClass(String name, RubyClass superClass, ObjectAllocator allocator, SinglyLinkedList parentCRef) { 28 super(name, RubyHash.class, superClass, allocator, parentCRef); 29 } 30 31 protected class HashMeta extends Meta { 32 protected void initializeClass() { 33 includeModule(getRuntime().getModule("Enumerable")); 34 35 defineFastMethod("==", Arity.singleArgument(), "equal"); 36 defineFastMethod("[]", Arity.singleArgument(), "aref"); 37 defineFastMethod("[]=", Arity.twoArguments(), "aset"); 38 defineFastMethod("clear", Arity.noArguments(), "rb_clear"); 39 defineMethod("default", Arity.optional(), "getDefaultValue"); 40 defineMethod("default_proc", Arity.noArguments()); 41 defineFastMethod("default=", Arity.singleArgument(), "setDefaultValue"); 43 defineMethod("delete", Arity.singleArgument()); 44 defineMethod("delete_if", Arity.noArguments()); 45 defineMethod("each", Arity.noArguments()); 46 defineMethod("each_pair", Arity.noArguments()); 47 defineMethod("each_value", Arity.noArguments()); 48 defineMethod("each_key", Arity.noArguments()); 49 defineFastMethod("empty?", Arity.noArguments(), "empty_p"); 50 defineMethod("fetch", Arity.optional()); 51 defineFastMethod("has_value?", Arity.singleArgument(), "has_value"); 52 defineFastMethod("index", Arity.singleArgument()); 53 defineFastMethod("indices", Arity.optional()); 54 defineMethod("initialize", Arity.optional()); 55 defineFastMethod("initialize_copy", Arity.singleArgument(), "replace"); 56 defineFastMethod("inspect", Arity.noArguments()); 57 defineFastMethod("invert", Arity.noArguments()); 58 defineFastMethod("include?", Arity.singleArgument(), "has_key"); 59 defineFastMethod("keys", Arity.noArguments()); 60 defineMethod("merge", Arity.singleArgument()); 61 defineFastMethod("rehash", Arity.noArguments()); 62 defineMethod("reject", Arity.noArguments()); 63 defineMethod("reject!", Arity.noArguments(), "reject_bang"); 64 defineFastMethod("replace", Arity.singleArgument()); 65 defineFastMethod("shift", Arity.noArguments()); 66 defineFastMethod("size", Arity.noArguments(), "rb_size"); 67 defineMethod("sort", Arity.noArguments()); 68 defineFastMethod("to_a", Arity.noArguments()); 69 defineFastMethod("to_hash", Arity.noArguments()); 70 defineFastMethod("to_s", Arity.noArguments()); 71 defineMethod("update", Arity.singleArgument()); 72 defineFastMethod("values", Arity.noArguments(), "rb_values"); 73 defineFastMethod("values_at", Arity.optional()); 74 75 defineAlias("has_key?", "include?"); 76 defineAlias("indexes", "indices"); 77 defineAlias("key?", "include?"); 78 defineAlias("length", "size"); 79 defineAlias("member?", "include?"); 80 defineAlias("merge!", "update"); 81 defineAlias("store", "[]="); 82 defineAlias("value?", "has_value?"); 83 84 CallbackFactory hashCB = getRuntime().callbackFactory(HashMetaClass.class); 85 86 getMetaClass().defineMethod("new", hashCB.getOptSingletonMethod("newInstance")); 87 getMetaClass().defineFastMethod("[]", hashCB.getOptSingletonMethod("create")); 88 } 89 }; 90 91 protected Meta getMeta() { 92 return new HashMeta(); 93 } 94 95 public RubyClass newSubClass(String name, SinglyLinkedList parentCRef) { 96 return new HashMetaClass(name, this, HASH_ALLOCATOR, parentCRef); 97 } 98 99 private static ObjectAllocator HASH_ALLOCATOR = new ObjectAllocator() { 100 public IRubyObject allocate(Ruby runtime, RubyClass klass) { 101 RubyHash instance = new RubyHash(runtime); 102 103 instance.setMetaClass(klass); 104 105 return instance; 106 } 107 }; 108 109 public static IRubyObject newInstance(IRubyObject recv, IRubyObject[] args, Block block) { 110 RubyHash hash = (RubyHash) ((RubyClass) recv).allocate(); 111 112 hash.callInit(args, block); 113 114 return hash; 115 } 116 117 public static IRubyObject create(IRubyObject recv, IRubyObject[] args, Block block) { 118 Ruby runtime = recv.getRuntime(); 119 RubyClass klass = (RubyClass) recv; 120 RubyHash hash = (RubyHash) klass.allocate(); 121 122 if (args.length == 1) { 123 hash.setValueMap(new HashMap (((RubyHash) args[0]).getValueMap())); 124 } else if (args.length % 2 != 0) { 125 throw runtime.newArgumentError("odd number of args for Hash"); 126 } else { 127 for (int i = 0; i < args.length; i += 2) { 128 hash.aset(args[i], args[i + 1]); 129 } 130 } 131 return hash; 132 } 133 } 134 | Popular Tags |