Last active
October 3, 2019 12:36
-
-
Save p7g/a813de640194e7d080d6b1b42f5717d9 to your computer and use it in GitHub Desktop.
A little object system written in Python, inspired by https://www.aosabook.org/en/500L/a-simple-object-model.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Type: | |
def __init__(self, name, *, method_table=None, parent=None): | |
self.name = name | |
self.method_table = method_table or {} | |
self.parent = parent | |
def resolve_method(self, name, /): | |
if name in self.method_table: | |
return self.method_table[name] | |
elif self.parent is not None: | |
return self.parent.resolve_method(name) | |
return None | |
TYPE = Type('type') | |
class Method: | |
def __init__(self, function, /): | |
self.function = function | |
def call(self, instance, /, args, kwargs): | |
return self.function(instance, *args, **kwargs) | |
method = Method | |
@method | |
def typeof(instance): | |
return instance.base.name | |
Object = Type('Object', method_table={'typeof': typeof}, parent=TYPE) | |
class Instance: | |
def __init__(self, base, args=(), kwargs=None): | |
kwargs = kwargs or {} | |
self.base = base | |
self.fields = {} | |
if init := self.base.resolve_method('__init__'): | |
init.call(self, args, kwargs) | |
def call_method(self, name, /, args=(), kwargs=None): | |
kwargs = kwargs or {} | |
if method := self.base.resolve_method(name): | |
return method.call(self, args, kwargs) | |
raise AttributeError(name) | |
def getattr(self, name, /): | |
if name in self.fields: | |
return self.fields[name] | |
raise AttributeError(name) | |
def setattr(self, name, value, /): | |
self.fields[name] = value | |
def delattr(self, name): | |
if name in self.fields: | |
del self.fields[name] | |
return True | |
return False | |
@method | |
def get_name(self): | |
return self.getattr('name') | |
@method | |
def set_name(self, name, /): | |
return self.setattr('name', name) | |
@method | |
def Test_init(self, name): | |
self.setattr('name', name) | |
Test = Type('Test', method_table={ | |
'get_name': get_name, | |
'set_name': set_name, | |
'__init__': Test_init, | |
}, parent=Object) | |
test = Instance(Test, kwargs={'name': 'hullo'}) | |
print('get_name:', test.call_method('get_name')) | |
print('typeof:', test.call_method('typeof')) | |
print('set_name', test.call_method('set_name', args=('world',))) | |
print('get_name:', test.call_method('get_name')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment