corelib/kernel.rb in opal-0.4.4 vs corelib/kernel.rb in opal-0.5.0

- old
+ new

@@ -1,74 +1,64 @@ module Kernel - # bridged from BasicObject - alias :initialize :initialize - alias :== :== - alias :__send__ :__send__ - alias :eql? :eql? - alias :equal? :equal? - alias :instance_eval :instance_eval - alias :instance_exec :instance_exec - def method_missing(symbol, *args, &block) raise NoMethodError, "undefined method `#{symbol}' for #{inspect}" end def =~(obj) false end def ===(other) - `#{self} == other` + self == other end + def <=>(other) + %x{ + if (#{self == other}) { + return 0; + } + + return nil; + } + end + def method(name) %x{ - var recv = #{self}, - meth = recv['$' + name], - func = function() { - return meth.apply(recv, $slice.call(arguments, 0)); - }; + var meth = self['$' + name]; - if (!meth) { - #{ raise NameError }; + if (!meth || meth.rb_stub) { + #{raise NameError, "undefined method `#{name}' for class `#{self.class.name}'"}; } - func._klass = #{Method}; - return func; + return #{Method.new(self, `meth`, name)}; } end def methods(all = true) %x{ var methods = []; - for(var k in #{self}) { - if(k[0] == "$" && typeof (#{self})[k] === "function") { + for(var k in self) { + if(k[0] == "$" && typeof (self)[k] === "function") { if(all === #{false} || all === #{nil}) { - if(!Object.hasOwnProperty.call(#{self}, k)) { + if(!Object.hasOwnProperty.call(self, k)) { continue; } } methods.push(k.substr(1)); } } return methods; } end - def Array(object, func = undefined, length = :length) + def Array(object, *args, &block) %x{ if (object == null || object === nil) { return []; } - else if (#{native?(object)} && object[length] != null) { - var result = []; - - for (var i = 0, length = object[length]; i < length; i++) { - result.push(func ? object[func](i) : object[i]); - } - - return result; + else if (#{native?(object)}) { + return #{Native::Array.new(object, *args, &block).to_a}; } else if (#{object.respond_to? :to_ary}) { return #{object.to_ary}; } else if (#{object.respond_to? :to_a}) { @@ -78,50 +68,69 @@ return [object]; } } end + # Opal does not support #caller, but we stub it as an empty array to not + # break dependant libs + def caller + [] + end + def class - `#{self}._klass` + `self._klass` end def define_singleton_method(name, &body) %x{ if (body === nil) { throw new Error("no block given"); } var jsid = '$' + name; - body._jsid = jsid; - body._sup = #{self}[jsid]; + body._jsid = name; body._s = null; + body._def = body; - #{self}[jsid] = body; + #{self.singleton_class}._proto[jsid] = body; - return #{self}; + return self; } end def dup - self.class.allocate + copy = self.class.allocate + + %x{ + for (var name in self) { + if (name.charAt(0) !== '$') { + if (name !== '_id' && name !== '_klass') { + copy[name] = self[name]; + } + } + } + } + + copy.initialize_copy self + copy end def enum_for(method = :each, *args) Enumerator.new self, method, *args end def equal?(other) - `#{self} === other` + `self === other` end def extend(*mods) %x{ for (var i = 0, length = mods.length; i < length; i++) { #{ self.singleton_class.include `mods[i]` }; } - return #{self}; + return self; } end def format(format, *args) %x{ @@ -251,74 +260,113 @@ }); } end def hash - `#{self}._id` + `self._id` end + def initialize_copy(other) + end + def inspect to_s end def instance_of?(klass) - `#{self}._klass === klass` + `self._klass === klass` end def instance_variable_defined?(name) - `#{self}.hasOwnProperty(name.substr(1))` + `self.hasOwnProperty(name.substr(1))` end def instance_variable_get(name) %x{ - var ivar = #{self}[name.substr(1)]; + var ivar = self[name.substr(1)]; return ivar == null ? nil : ivar; } end def instance_variable_set(name, value) - `#{self}[name.substr(1)] = value` + `self[name.substr(1)] = value` end def instance_variables %x{ var result = []; - for (var name in #{self}) { + for (var name in self) { if (name.charAt(0) !== '$') { - result.push(name); + if (name !== '_klass' && name !== '_id') { + result.push('@' + name); + } } } return result; } end - def Integer(str) - `parseInt(str)` - end + def Integer(value, base = nil) + if String === value + if value.empty? + raise ArgumentError, "invalid value for Integer: (empty string)" + end - def is_a?(klass) - %x{ - var search = #{self}._klass; + return `parseInt(#{value}, #{base || `undefined`})` + end - while (search) { - if (search === klass) { - return true; - } + if base + raise ArgumentError "base is only valid for String values" + end - search = search._super; - } + case value + when Integer + value - return false; - } + when Float + if value.nan? or value.infinite? + raise FloatDomainError, "unable to coerce #{value} to Integer" + end + + value.to_int + + when NilClass + raise TypeError, "can't convert nil into Integer" + + else + if value.respond_to? :to_int + value.to_int + elsif value.respond_to? :to_i + value.to_i + else + raise TypeError, "can't convert #{value.class} into Integer" + end + end end + def Float(value) + if String === value + `parseFloat(value)` + elsif value.respond_to? :to_f + value.to_f + else + raise TypeError, "can't convert #{value.class} into Float" + end + end + + def is_a?(klass) + `$opal.is_a(self, klass)` + end + alias kind_of? is_a? def lambda(&block) + `block.is_lambda = true` + block end def loop(&block) `while (true) {` @@ -331,21 +379,25 @@ def nil? false end def object_id - `#{self}._id || (#{self}._id = Opal.uid())` + `self._id || (self._id = Opal.uid())` end def printf(*args) if args.length > 0 fmt = args.shift print format(fmt, *args) end nil end + def private_methods + [] + end + def proc(&block) %x{ if (block === nil) { #{ raise ArgumentError, 'no block given' }; } @@ -364,23 +416,33 @@ args.length <= 1 ? args[0] : args end alias print puts - def raise(exception = "", string = undefined) + def warn(*strs) + $stderr.puts(*strs) unless $VERBOSE.nil? || strs.empty? + nil + end + + def raise(exception = undefined, string = undefined) %x{ - if (typeof(exception) === 'string') { + if (exception == null && #$!) { + exception = #$!; + } + else if (typeof(exception) === 'string') { exception = #{RuntimeError.new exception}; } else if (!#{exception.is_a? Exception}) { exception = #{exception.new string}; } throw exception; } end + alias fail raise + def rand(max = undefined) %x{ if(!max) { return Math.random(); } else { @@ -392,60 +454,65 @@ } } } end - def respond_to?(name) + alias srand rand + + def respond_to?(name, include_all = false) %x{ - var body = #{self}['$' + name]; + var body = self['$' + name]; return (!!body) && !body.rb_stub; } end alias send __send__ alias public_send __send__ def singleton_class %x{ - if (#{self}._isClass) { - if (#{self}._singleton) { - return #{self}._singleton; + if (self._isClass) { + if (self.__meta__) { + return self.__meta__; } var meta = new $opal.Class._alloc; meta._klass = $opal.Class; - #{self}._singleton = meta; + self.__meta__ = meta; // FIXME - is this right? (probably - methods defined on // class' singleton should also go to subclasses?) - meta._proto = #{self}.constructor.prototype; + meta._proto = self.constructor.prototype; meta._isSingleton = true; + meta.__inc__ = []; + meta._methods = []; - meta._scope = #{self}._scope; + meta._scope = self._scope; return meta; } - if (#{self}._isClass) { - return #{self}._klass; + if (self._isClass) { + return self._klass; } - if (#{self}._singleton) { - return #{self}._singleton; + if (self.__meta__) { + return self.__meta__; } else { - var orig_class = #{self}._klass, + var orig_class = self._klass, class_id = "#<Class:#<" + orig_class._name + ":" + orig_class._id + ">>"; var Singleton = function () {}; var meta = Opal.boot(orig_class, Singleton); meta._name = class_id; - meta._proto = #{self}; - #{self}._singleton = meta; + meta._proto = self; + self.__meta__ = meta; meta._klass = orig_class._klass; meta._scope = orig_class._scope; + meta.__parent = orig_class; return meta; } } end @@ -464,19 +531,21 @@ def to_proc self end def to_s - `return "#<" + #{self}._klass._name + ":" + #{self}._id + ">";` + `"#<" + self._klass._name + ":" + self._id + ">"` end - alias to_str to_s - def freeze @___frozen___ = true self end def frozen? @___frozen___ || false + end + + def respond_to_missing? method_name + false end end