opal/corelib/runtime.js in opal-1.0.5 vs opal/corelib/runtime.js in opal-1.1.0.rc1
- old
+ new
@@ -1,6 +1,8 @@
-(function(undefined) {
+(function(global_object) {
+ "use strict";
+
// @note
// A few conventions for the documentation of this file:
// 1. Always use "//" (in contrast with "/**/")
// 2. The syntax used is Yardoc (yardoc.org), which is intended for Ruby (se below)
// 3. `@param` and `@return` types should be preceded by `JS.` when referring to
@@ -11,15 +13,16 @@
// to improve or for alternative solutions
//
// The way the code is digested before going through Yardoc is a secret kept
// in the docs repo (https://github.com/opal/docs/tree/master).
- var global_object = this, console;
+ var console;
// Detect the global object
- if (typeof(global) !== 'undefined') { global_object = global; }
- if (typeof(window) !== 'undefined') { global_object = window; }
+ if (typeof(globalThis) !== 'undefined') { global_object = globalThis; }
+ else if (typeof(global) !== 'undefined') { global_object = global; }
+ else if (typeof(window) !== 'undefined') { global_object = window; }
// Setup a dummy console object if missing
if (typeof(global_object.console) === 'object') {
console = global_object.console;
} else if (global_object.console == null) {
@@ -29,13 +32,13 @@
}
if (!('log' in console)) { console.log = function () {}; }
if (!('warn' in console)) { console.warn = console.log; }
- if (typeof(this.Opal) !== 'undefined') {
+ if (typeof(global_object.Opal) !== 'undefined') {
console.warn('Opal already loaded. Loading twice can cause troubles, please fix your setup.');
- return this.Opal;
+ return global_object.Opal;
}
var nil;
// The actual class for BasicObject
@@ -50,29 +53,29 @@
// The actual Class class
var Class;
// The Opal object that is exposed globally
- var Opal = this.Opal = {};
+ var Opal = global_object.Opal = {};
// This is a useful reference to global object inside ruby files
Opal.global = global_object;
global_object.Opal = Opal;
- // Configure runtime behavior with regards to require and unsupported fearures
+ // Configure runtime behavior with regards to require and unsupported features
Opal.config = {
missing_require_severity: 'error', // error, warning, ignore
unsupported_features_severity: 'warning', // error, warning, ignore
enable_stack_trace: true // true, false
};
// Minify common function calls
- var $hasOwn = Object.hasOwnProperty;
- var $bind = Function.prototype.bind;
- var $setPrototype = Object.setPrototypeOf;
- var $slice = Array.prototype.slice;
- var $splice = Array.prototype.splice;
+ var $has_own = Object.hasOwnProperty;
+ var $bind = Function.prototype.bind;
+ var $set_proto = Object.setPrototypeOf;
+ var $slice = Array.prototype.slice;
+ var $splice = Array.prototype.splice;
// Nil object id is always 4
var nil_id = 4;
// Generates even sequential numbers greater than 4
@@ -133,11 +136,11 @@
// s = "string"
// def s.m; end
// String class is the only class that:
// + compiles to JS primitive
// + allows method definition directly on instances
- // numbers, true, false and nil do not support it.
+ // numbers, true, false and null do not support it.
object[name] = initialValue;
} else {
Object.defineProperty(object, name, {
value: initialValue,
enumerable: false,
@@ -150,22 +153,65 @@
Opal.defineProperty = $defineProperty;
Opal.slice = $slice;
- // Truth
+ // Helpers
// -----
Opal.truthy = function(val) {
return (val !== nil && val != null && (!val.$$is_boolean || val == true));
};
Opal.falsy = function(val) {
return (val === nil || val == null || (val.$$is_boolean && val == false))
};
+ Opal.type_error = function(object, type, method, coerced) {
+ object = object.$$class;
+ if (coerced && method) {
+ coerced = coerced.$$class;
+ return Opal.TypeError.$new(
+ "can't convert " + object + " into " + type +
+ " (" + object + "#" + method + " gives " + coerced + ")"
+ )
+ } else {
+ return Opal.TypeError.$new(
+ "no implicit conversion of " + object + " into " + type
+ )
+ }
+ };
+
+ Opal.coerce_to = function(object, type, method, args) {
+ if (type['$==='](object)) return object;
+
+ if (!object['$respond_to?'](method)) {
+ throw Opal.type_error(object, type);
+ }
+
+ if (args == null) args = [];
+ return Opal.send(object, method, args);
+ }
+
+ Opal.respond_to = function(obj, jsid, include_all) {
+ if (obj == null || !obj.$$class) return false;
+ include_all = !!include_all;
+ var body = obj[jsid];
+
+ if (obj['$respond_to?'].$$pristine) {
+ if (obj['$respond_to_missing?'].$$pristine) {
+ return typeof(body) === "function" && !body.$$stub;
+ } else {
+ return Opal.send(obj, obj['$respond_to_missing?'], [jsid.substr(1), include_all]);
+ }
+ } else {
+ return Opal.send(obj, obj['$respond_to?'], [jsid.substr(1), include_all]);
+ }
+ }
+
+
// Constants
// ---------
//
// For future reference:
// - The Rails autoloading guide (http://guides.rubyonrails.org/v5.0/autoloading_and_reloading_constants.html)
@@ -181,11 +227,11 @@
if (cref) return cref.$$const[name];
}
// Walk up the nesting array looking for the constant
function const_lookup_nesting(nesting, name) {
- var i, ii, result, constant;
+ var i, ii, constant;
if (nesting.length === 0) return;
// If the nesting is not empty the constant is looked up in its elements
// and in order. The ancestors of those elements are ignored.
@@ -195,18 +241,18 @@
}
}
// Walk up the ancestors chain looking for the constant
function const_lookup_ancestors(cref, name) {
- var i, ii, result, ancestors;
+ var i, ii, ancestors;
if (cref == null) return;
ancestors = Opal.ancestors(cref);
for (i = 0, ii = ancestors.length; i < ii; i++) {
- if (ancestors[i].$$const && $hasOwn.call(ancestors[i].$$const, name)) {
+ if (ancestors[i].$$const && $has_own.call(ancestors[i].$$const, name)) {
return ancestors[i].$$const[name];
}
}
}
@@ -331,19 +377,19 @@
// Get all the constants reachable from a given cref, by default will include
// inherited constants.
Opal.constants = function(cref, inherit) {
if (inherit == null) inherit = true;
- var module, modules = [cref], module_constants, i, ii, constants = {}, constant;
+ var module, modules = [cref], i, ii, constants = {}, constant;
if (inherit) modules = modules.concat(Opal.ancestors(cref));
if (inherit && cref.$$is_module) modules = modules.concat([Opal.Object]).concat(Opal.ancestors(Opal.Object));
for (i = 0, ii = modules.length; i < ii; i++) {
module = modules[i];
- // Don not show Objects constants unless we're querying Object itself
+ // Do not show Objects constants unless we're querying Object itself
if (cref !== _Object && module == _Object) break;
for (constant in module.$$const) {
constants[constant] = true;
}
@@ -368,11 +414,15 @@
}
throw Opal.NameError.$new("constant "+cref+"::"+cref.$name()+" not defined");
};
+ // Setup some shortcuts to reduce compiled size
+ Opal.$$ = Opal.const_get_relative;
+ Opal.$$$ = Opal.const_get_qualified;
+
// Modules & Classes
// -----------------
// A `class Foo; end` expression in ruby is compiled to call this runtime
// method which either returns an existing class of the given name, or creates
@@ -408,11 +458,11 @@
constructor = function() {
var args = $slice.call(arguments),
self = new ($bind.apply(superclass.$$constructor, [null].concat(args)))();
// and replacing a __proto__ manually
- $setPrototype(self, klass.$$prototype);
+ $set_proto(self, klass.$$prototype);
return self;
}
} else {
constructor = function(){};
}
@@ -441,15 +491,15 @@
// By default if there are no singleton class methods
// __proto__ is Class.prototype
// Later singleton methods generate a singleton_class
// and inject it into ancestors chain
if (Opal.Class) {
- $setPrototype(klass, Opal.Class.prototype);
+ $set_proto(klass, Opal.Class.prototype);
}
if (superclass != null) {
- $setPrototype(klass.$$prototype, superclass.$$prototype);
+ $set_proto(klass.$$prototype, superclass.$$prototype);
if (superclass.$$meta) {
// If superclass has metaclass then we have explicitely inherit it.
Opal.build_class_singleton_class(klass);
}
@@ -570,11 +620,11 @@
$defineProperty(module, '$$own_included_modules', []);
$defineProperty(module, '$$own_prepended_modules', []);
$defineProperty(module, '$$ancestors', [module]);
$defineProperty(module, '$$ancestors_cache_version', null);
- $setPrototype(module, Opal.Module.prototype);
+ $set_proto(module, Opal.Module.prototype);
return module;
};
function find_existing_module(scope, name) {
@@ -631,11 +681,11 @@
}
if (object.hasOwnProperty('$$is_class')) {
return Opal.build_class_singleton_class(object);
} else if (object.hasOwnProperty('$$is_module')) {
- return Opal.build_module_singletin_class(object);
+ return Opal.build_module_singleton_class(object);
} else {
return Opal.build_object_singleton_class(object);
}
};
@@ -663,28 +713,28 @@
meta = Opal.allocate_class(null, superclass, function(){});
$defineProperty(meta, '$$is_singleton', true);
$defineProperty(meta, '$$singleton_of', klass);
$defineProperty(klass, '$$meta', meta);
- $setPrototype(klass, meta.$$prototype);
+ $set_proto(klass, meta.$$prototype);
// Restoring ClassName.class
$defineProperty(klass, '$$class', Opal.Class);
return meta;
};
- Opal.build_module_singletin_class = function(mod) {
+ Opal.build_module_singleton_class = function(mod) {
if (mod.$$meta) {
return mod.$$meta;
}
var meta = Opal.allocate_class(null, Opal.Module, function(){});
$defineProperty(meta, '$$is_singleton', true);
$defineProperty(meta, '$$singleton_of', mod);
$defineProperty(mod, '$$meta', meta);
- $setPrototype(mod, meta.$$prototype);
+ $set_proto(mod, meta.$$prototype);
// Restoring ModuleName.class
$defineProperty(mod, '$$class', Opal.Module);
return meta;
};
@@ -702,11 +752,11 @@
delete klass.$$prototype.$$class;
$defineProperty(object, '$$meta', klass);
- $setPrototype(object, object.$$meta.$$prototype);
+ $set_proto(object, object.$$meta.$$prototype);
return klass;
};
Opal.is_method = function(prop) {
@@ -821,11 +871,11 @@
i, length = ancestors.length;
for (i = length - 2; i >= 0; i--) {
var ancestor = ancestors[i];
- if ($hasOwn.call(ancestor.$$cvars, name)) {
+ if ($has_own.call(ancestor.$$cvars, name)) {
ancestor.$$cvars[name] = value;
return value;
}
}
@@ -967,12 +1017,12 @@
start_chain_after = parent;
end_chain_on = next_ancestor;
}
- $setPrototype(start_chain_after, chain.first);
- $setPrototype(chain.last, end_chain_on);
+ $set_proto(start_chain_after, chain.first);
+ $set_proto(chain.last, end_chain_on);
// recalculate own_included_modules cache
includer.$$own_included_modules = own_included_modules(includer);
Opal.const_cache_version++;
@@ -1027,12 +1077,12 @@
// Converting
// dummy(prepender) -> previous_parent
// to
// dummy(prepender) -> iclass(prepender) -> previous_parent
- $setPrototype(dummy_prepender, prepender_iclass);
- $setPrototype(prepender_iclass, previous_parent);
+ $set_proto(dummy_prepender, prepender_iclass);
+ $set_proto(prepender_iclass, previous_parent);
}
var prepender_ancestors = Opal.ancestors(prepender);
if (prepender_ancestors.indexOf(module) === -1) {
@@ -1055,12 +1105,12 @@
}
} else {
throw Opal.RuntimeError.$new("Prepending a module multiple times is not supported");
}
- $setPrototype(start_chain_after, chain.first);
- $setPrototype(chain.last, end_chain_on);
+ $set_proto(start_chain_after, chain.first);
+ $set_proto(chain.last, end_chain_on);
// recalculate own_prepended_modules cache
prepender.$$own_prepended_modules = own_prepended_modules(prepender);
Opal.const_cache_version++;
@@ -1122,11 +1172,11 @@
var previous = first;
for (var i = 1; i < length; i++) {
var current = iclasses[i];
- $setPrototype(previous, current);
+ $set_proto(previous, current);
previous = current;
}
return { first: iclasses[0], last: iclasses[length - 1] };
@@ -1152,16 +1202,10 @@
Opal.bridge = function(native_klass, klass) {
if (native_klass.hasOwnProperty('$$bridge')) {
throw Opal.ArgumentError.$new("already bridged");
}
- var klass_to_inject, klass_reference;
-
- klass_to_inject = klass.$$super || Opal.Object;
- klass_reference = klass;
- var original_prototype = klass.$$prototype;
-
// constructor is a JS function with a prototype chain like:
// - constructor
// - super
//
// What we need to do is to inject our class (with its prototype chain)
@@ -1174,11 +1218,11 @@
// - Opal.BasicObject
// - super (window.Object)
// - null
//
$defineProperty(native_klass, '$$bridge', klass);
- $setPrototype(native_klass.prototype, (klass.$$super || Opal.Object).$$prototype);
+ $set_proto(native_klass.prototype, (klass.$$super || Opal.Object).$$prototype);
$defineProperty(klass, '$$prototype', native_klass.prototype);
$defineProperty(klass.$$prototype, '$$class', klass);
$defineProperty(klass, '$$constructor', native_klass);
$defineProperty(klass, '$$bridge', true);
@@ -1294,11 +1338,14 @@
// Generate the method_missing stub for a given method name.
//
// @param method_name [String] The js-name of the method to stub (e.g. "$foo")
// @return [undefined]
Opal.stub_for = function(method_name) {
+
function method_missing_stub() {
+ /* jshint validthis: true */
+
// Copy any given block onto the method_missing dispatcher
this.$method_missing.$$p = method_missing_stub.$$p;
// Set block property to null ready for the next call (stop false-positives)
method_missing_stub.$$p = null;
@@ -1350,11 +1397,11 @@
throw Opal.ArgumentError.$new(inspect + ': wrong number of arguments (' + actual + ' for ' + expected + ')');
};
// Super dispatcher
- Opal.find_super_dispatcher = function(obj, mid, current_func, defcheck, defs) {
+ Opal.find_super_dispatcher = function(obj, mid, current_func, defcheck, allow_stubs) {
var jsid = '$' + mid, ancestors, super_method;
if (obj.hasOwnProperty('$$meta')) {
ancestors = Opal.ancestors(obj.$$meta);
} else {
@@ -1370,25 +1417,21 @@
if (proto.hasOwnProperty('$$dummy')) {
proto = proto.$$define_methods_on;
}
if (proto.hasOwnProperty(jsid)) {
- var method = proto[jsid];
-
- if (!method.$$stub) {
- super_method = method;
- }
+ super_method = proto[jsid];
break;
}
}
- if (!defcheck && super_method == null && Opal.Kernel.$method_missing === obj.$method_missing) {
+ if (!defcheck && super_method && super_method.$$stub && obj.$method_missing.$$pristine) {
// method_missing hasn't been explicitly defined
throw Opal.NoMethodError.$new('super: no superclass method `'+mid+"' for "+obj, mid);
}
- return super_method;
+ return (super_method.$$stub && !allow_stubs) ? null : super_method;
};
// Iter dispatcher for super in a block
Opal.find_iter_super_dispatcher = function(obj, jsid, current_func, defcheck, implicit) {
var call_jsid = jsid;
@@ -1503,11 +1546,11 @@
if (klass != null && object.$$meta === klass || object.$$class === klass) {
return true;
}
if (object.$$is_number && klass.$$is_number_class) {
- return true;
+ return (klass.$$is_integer_class) ? (object % 1) === 0 : true;
}
var i, length, ancestors = Opal.ancestors(object.$$is_class ? Opal.get_singleton_class(object) : (object.$$meta || object.$$class));
for (i = 0, length = ancestors.length; i < length; i++) {
@@ -1599,11 +1642,11 @@
// @param parameters [Array]
// @return [Hash]
//
Opal.extract_kwargs = function(parameters) {
var kwargs = parameters[parameters.length - 1];
- if (kwargs != null && kwargs['$respond_to?']('to_hash', true)) {
+ if (kwargs != null && Opal.respond_to(kwargs, '$to_hash', true)) {
$splice.call(parameters, parameters.length - 1, 1);
return kwargs.$to_hash();
}
else {
return Opal.hash2([], {});
@@ -1660,22 +1703,34 @@
// @param method [Function, String] method body or name of the method
// @param args [Array] arguments that will be passed to the method call
// @param block [Function] ruby block
// @return [Object] returning value of the method call
Opal.send = function(recv, method, args, block) {
- var body = (typeof(method) === 'string') ? recv['$'+method] : method;
+ var body;
- if (body != null) {
- if (typeof block === 'function') {
- body.$$p = block;
- }
- return body.apply(recv, args);
+ if (typeof(method) === 'function') {
+ body = method;
+ method = null;
+ } else if (typeof(method) === 'string') {
+ body = recv['$'+method];
+ } else {
+ throw Opal.NameError.$new("Passed method should be a string or a function");
}
- return recv.$method_missing.apply(recv, [method].concat(args));
+ return Opal.send2(recv, body, method, args, block);
};
+ Opal.send2 = function(recv, body, method, args, block) {
+ if (body == null && method != null && recv.$method_missing) {
+ body = recv.$method_missing;
+ args = [method].concat(args);
+ }
+
+ if (typeof block === 'function') body.$$p = block;
+ return body.apply(recv, args);
+ };
+
Opal.lambda = function(block) {
block.$$is_lambda = true;
return block;
};
@@ -1769,11 +1824,11 @@
Opal.defn(Opal.get_singleton_class(obj), jsid, body)
};
// Called from #remove_method.
Opal.rdef = function(obj, jsid) {
- if (!$hasOwn.call(obj.$$prototype, jsid)) {
+ if (!$has_own.call(obj.$$prototype, jsid)) {
throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
}
delete obj.$$prototype[jsid];
@@ -1845,11 +1900,11 @@
// If the body is itself an alias use the original body
// to keep the max depth at 1.
if (body.$$alias_of) body = body.$$alias_of;
// We need a wrapper because otherwise properties
- // would be ovrewritten on the original body.
+ // would be overwritten on the original body.
alias = function() {
var block = alias.$$p, args, i, ii;
args = new Array(arguments.length);
for(i = 0, ii = arguments.length; i < ii; i++) {
@@ -1859,13 +1914,21 @@
if (block != null) { alias.$$p = null }
return Opal.send(this, body, args, block);
};
+ // Assign the 'length' value with defineProperty because
+ // in strict mode the property is not writable.
+ // It doesn't work in older browsers (like Chrome 38), where
+ // an exception is thrown breaking Opal altogether.
+ try {
+ Object.defineProperty(alias, 'length', { value: body.length });
+ } catch (e) {}
+
// Try to make the browser pick the right name
alias.displayName = name;
- alias.length = body.length;
+
alias.$$arity = body.$$arity;
alias.$$parameters = body.$$parameters;
alias.$$source_location = body.$$source_location;
alias.$$alias_of = body;
alias.$$alias_name = name;
@@ -1916,21 +1979,21 @@
}
};
Opal.hash_put = function(hash, key, value) {
if (key.$$is_string) {
- if (!$hasOwn.call(hash.$$smap, key)) {
+ if (!$has_own.call(hash.$$smap, key)) {
hash.$$keys.push(key);
}
hash.$$smap[key] = value;
return;
}
var key_hash, bucket, last_bucket;
key_hash = hash.$$by_identity ? Opal.id(key) : key.$hash();
- if (!$hasOwn.call(hash.$$map, key_hash)) {
+ if (!$has_own.call(hash.$$map, key_hash)) {
bucket = {key: key, key_hash: key_hash, value: value};
hash.$$keys.push(bucket);
hash.$$map[key_hash] = bucket;
return;
}
@@ -1954,20 +2017,20 @@
}
};
Opal.hash_get = function(hash, key) {
if (key.$$is_string) {
- if ($hasOwn.call(hash.$$smap, key)) {
+ if ($has_own.call(hash.$$smap, key)) {
return hash.$$smap[key];
}
return;
}
var key_hash, bucket;
key_hash = hash.$$by_identity ? Opal.id(key) : key.$hash();
- if ($hasOwn.call(hash.$$map, key_hash)) {
+ if ($has_own.call(hash.$$map, key_hash)) {
bucket = hash.$$map[key_hash];
while (bucket) {
if (key === bucket.key || key['$eql?'](bucket.key)) {
return bucket.value;
@@ -1979,11 +2042,13 @@
Opal.hash_delete = function(hash, key) {
var i, keys = hash.$$keys, length = keys.length, value;
if (key.$$is_string) {
- if (!$hasOwn.call(hash.$$smap, key)) {
+ if (typeof key !== "string") key = key.valueOf();
+
+ if (!$has_own.call(hash.$$smap, key)) {
return;
}
for (i = 0; i < length; i++) {
if (keys[i] === key) {
@@ -1997,11 +2062,11 @@
return value;
}
var key_hash = key.$hash();
- if (!$hasOwn.call(hash.$$map, key_hash)) {
+ if (!$has_own.call(hash.$$map, key_hash)) {
return;
}
var bucket = hash.$$map[key_hash], last_bucket;
@@ -2072,11 +2137,11 @@
bucket = bucket.next;
}
hash.$$keys[i].key_hash = key_hash;
- if (!$hasOwn.call(hash.$$map, key_hash)) {
+ if (!$has_own.call(hash.$$map, key_hash)) {
hash.$$map[key_hash] = hash.$$keys[i];
continue;
}
bucket = hash.$$map[key_hash];
@@ -2126,11 +2191,11 @@
}
if (arguments_length === 1) {
args = arguments[0];
for (key in args) {
- if ($hasOwn.call(args, key)) {
+ if ($has_own.call(args, key)) {
value = args[key];
Opal.hash_put(hash, key, value);
}
}
@@ -2255,10 +2320,37 @@
}
result.lastIndex = null; // reset lastIndex property
return result;
};
+ // Combine multiple regexp parts together
+ Opal.regexp = function(parts, flags) {
+ var part;
+ var ignoreCase = typeof flags !== 'undefined' && flags && flags.indexOf('i') >= 0;
+
+ for (var i = 0, ii = parts.length; i < ii; i++) {
+ part = parts[i];
+ if (part instanceof RegExp) {
+ if (part.ignoreCase !== ignoreCase)
+ Opal.Kernel.$warn(
+ "ignore case doesn't match for " + part.source.$inspect(),
+ Opal.hash({uplevel: 1})
+ )
+
+ part = part.source;
+ }
+ if (part === '') part = '(?:' + part + ')';
+ parts[i] = part;
+ }
+
+ if (flags) {
+ return new RegExp(parts.join(''), flags);
+ } else {
+ return new RegExp(parts.join(''));
+ }
+ };
+
// Require system
// --------------
Opal.modules = {};
Opal.loaded_features = ['corelib/runtime'];
@@ -2338,10 +2430,41 @@
return Opal.load(path);
};
+ // Strings
+ // -------
+
+ Opal.encodings = Object.create(null);
+
+ // Sets the encoding on a string, will treat string literals as frozen strings
+ // raising a FrozenError.
+ // @param str [String] the string on which the encoding should be set.
+ // @param name [String] the canonical name of the encoding
+ Opal.set_encoding = function(str, name) {
+ if (typeof str === 'string')
+ throw Opal.FrozenError.$new("can't modify frozen String");
+
+ var encoding = Opal.encodings[name];
+
+ if (encoding === str.encoding) { return str; }
+
+ str.encoding = encoding;
+
+ return str;
+ };
+
+ // @returns a String object with the encoding set from a string literal
+ Opal.enc = function(str, name) {
+ var dup = new String(str);
+ Opal.set_encoding(dup, name);
+ dup.internal_encoding = dup.encoding;
+ return dup
+ }
+
+
// Initialization
// --------------
function $BasicObject() {}
function $Object() {}
function $Module() {}
@@ -2350,14 +2473,14 @@
Opal.BasicObject = BasicObject = Opal.allocate_class('BasicObject', null, $BasicObject);
Opal.Object = _Object = Opal.allocate_class('Object', Opal.BasicObject, $Object);
Opal.Module = Module = Opal.allocate_class('Module', Opal.Object, $Module);
Opal.Class = Class = Opal.allocate_class('Class', Opal.Module, $Class);
- $setPrototype(Opal.BasicObject, Opal.Class.$$prototype);
- $setPrototype(Opal.Object, Opal.Class.$$prototype);
- $setPrototype(Opal.Module, Opal.Class.$$prototype);
- $setPrototype(Opal.Class, Opal.Class.$$prototype);
+ $set_proto(Opal.BasicObject, Opal.Class.$$prototype);
+ $set_proto(Opal.Object, Opal.Class.$$prototype);
+ $set_proto(Opal.Module, Opal.Class.$$prototype);
+ $set_proto(Opal.Class, Opal.Class.$$prototype);
// BasicObject can reach itself, avoid const_set to skip the $$base_module logic
BasicObject.$$const["BasicObject"] = BasicObject;
// Assign basic constants
@@ -2385,17 +2508,21 @@
// Make Kernel#require immediately available as it's needed to require all the
// other corelib files.
$defineProperty(_Object.$$prototype, '$require', Opal.require);
- // Add a short helper to navigate constants manually.
- // @example
- // Opal.$$.Regexp.$$.IGNORECASE
- Opal.$$ = _Object.$$;
-
// Instantiate the main object
Opal.top = new _Object();
Opal.top.$to_s = Opal.top.$inspect = function() { return 'main' };
+ Opal.top.$define_method = top_define_method;
+
+ // Foward calls to define_method on the top object to Object
+ function top_define_method() {
+ var args = Opal.slice.call(arguments, 0, arguments.length);
+ var block = top_define_method.$$p;
+ top_define_method.$$p = null;
+ return Opal.send(_Object, 'define_method', args, block)
+ };
// Nil
function $NilClass() {}
Opal.NilClass = Opal.allocate_class('NilClass', Opal.Object, $NilClass);