Skip to content
Permalink
Browse files

Merge pull request #672 from krekoten/module_remove_method

Module#remove_method and hooks
  • Loading branch information
alex committed May 2, 2013
2 parents 4f93593 + abfc791 commit 32c41273899af80d42fe9fdf045cba54060b896c
@@ -1,2 +1 @@
fails:BasicObject#singleton_method_removed is a private method
fails:BasicObject#singleton_method_removed is called when a method is removed on self
@@ -1,3 +1 @@
fails:Module#method_removed is a private instance method
fails:Module#method_removed returns nil in the default implementation
fails:Module#method_removed is called when a method is removed from self

This file was deleted.

@@ -10,10 +10,11 @@ class W_ClassObject(W_ModuleObject):

classdef = ClassDef("Class", W_ModuleObject.classdef, filepath=__file__)

def __init__(self, space, name, superclass, is_singleton=False):
def __init__(self, space, name, superclass, is_singleton=False, attached=None):
W_ModuleObject.__init__(self, space, name)
self.superclass = superclass
self.is_singleton = is_singleton
self.attached = attached

if self.superclass is not None:
self.superclass.inherited(space, self)
@@ -38,7 +39,7 @@ def getsingletonclass(self, space):
else:
name = "#<Class:%s>" % self.name
self.klass = space.newclass(
name, singleton_superclass, is_singleton=True
name, singleton_superclass, is_singleton=True, attached=self
)
return self.klass

@@ -74,6 +75,12 @@ def inherited(self, space, w_mod):
if not space.bootstrap and space.respond_to(self, space.newsymbol("inherited")):
space.send(self, space.newsymbol("inherited"), [w_mod])

def method_removed(self, space, w_name):
if self.is_singleton:
space.send(self.attached, space.newsymbol("singleton_method_removed"), [w_name])
else:
W_ModuleObject.method_removed(self, space, w_name)

@classdef.singleton_method("allocate")
def singleton_method_allocate(self, space, w_superclass=None):
if w_superclass is not None:
@@ -121,7 +121,7 @@ def getclass(self, space):
def getsingletonclass(self, space):
if self.klass is None or not self.klass.is_singleton:
self.klass = space.newclass(
"#<Class:%s>" % self.name, self.klass or space.w_module, is_singleton=True
"#<Class:%s>" % self.name, self.klass or space.w_module, is_singleton=True, attached=self
)
return self.klass

@@ -582,16 +582,26 @@ def method_undef_method(self, space, name):
return self

@classdef.method("remove_method", name="symbol")
@check_frozen()
def method_remove_method(self, space, name):
w_method = self._find_method_pure(space, name, self.version)
if w_method is None or isinstance(w_method, UndefMethod):
cls_name = space.obj_to_s(self)
raise space.error(space.w_NameError,
"method `%s' not defined in %s" % (name, cls_name)
)
self.define_method(space, name, UndefMethod(name))
del self.methods_w[name]
self.mutated()
self.method_removed(space, space.newsymbol(name))
return self

def method_removed(self, space, w_name):
space.send(self, space.newsymbol("method_removed"), [w_name])

@classdef.method("method_removed")
def method_method_removed(self, space, w_name):
return space.w_nil

@classdef.method("class_exec")
@classdef.method("module_exec")
def method_module_exec(self, space, args_w, block):
@@ -99,6 +99,10 @@ def method_instance_eval(self, space, string=None, filename=None, w_lineno=None,
else:
return space.invoke_block(block.copy(space, w_self=self), [])

@classdef.method("singleton_method_removed")
def method_singleton_method_removed(self, space, w_name):
return space.w_nil


class W_RootObject(W_BaseObject):
_attrs_ = []
@@ -205,14 +209,14 @@ def getsingletonclass(self, space):
w_cls = jit.promote(self.map).get_class()
if w_cls.is_singleton:
return w_cls
w_cls = space.newclass(w_cls.name, w_cls, is_singleton=True)
w_cls = space.newclass(w_cls.name, w_cls, is_singleton=True, attached=self)
self.map = self.map.change_class(space, w_cls)
return w_cls

def copy_singletonclass(self, space, w_other):
w_cls = jit.promote(self.map).get_class()
assert not w_cls.is_singleton
w_copy = space.newclass(w_cls.name, w_cls, is_singleton=True)
w_copy = space.newclass(w_cls.name, w_cls, is_singleton=True, attached=self)
w_copy.methods_w.update(w_other.methods_w)
w_copy.constants_w.update(w_other.constants_w)
w_copy.included_modules = w_copy.included_modules + w_other.included_modules
@@ -394,9 +394,9 @@ def newmodule(self, name, w_scope=None):
complete_name = self.buildname(name, w_scope)
return W_ModuleObject(self, complete_name)

def newclass(self, name, superclass, is_singleton=False, w_scope=None):
def newclass(self, name, superclass, is_singleton=False, w_scope=None, attached=None):
complete_name = self.buildname(name, w_scope)
return W_ClassObject(self, complete_name, superclass, is_singleton=is_singleton)
return W_ClassObject(self, complete_name, superclass, is_singleton=is_singleton, attached=attached)

def newfunction(self, w_name, w_code, lexical_scope):
name = self.symbol_w(w_name)

0 comments on commit 32c4127

Please sign in to comment.
You can’t perform that action at this time.