Edward Withers
Jun 12 2019: Reimplementing classes in ruby
Jump to comments
A short challenge to reimplement the class keyword in ruby.
I used Kernel#binding
to set scope.
Have a look here for the gist.
Pretty, huh?
module BasicClass
def self.new(parent_klass = nil, &block)
klass = lambda do
class_scope = {
ancestry: [klass, self],
instance_methods: {},
methods: {
define: lambda { |name, &block| class_scope[:instance_methods][name] = block },
new: lambda do |*args|
instance = lambda do
instance_scope = {
class_methods: class_scope[:methods].dup,
methods: class_scope[:instance_methods].dup,
instance_vars: {}
}
instance_scope[:methods][:initialize].call(instance_scope, *args)
binding
end
instance_scope = instance.call.local_variable_get('instance_scope')
instance
end
},
}
class_scope
end
class_scope = klass.call
block.call(class_scope)
klass
end
end
DockingStation = BasicClass.new do |class_scope|
class_scope[:methods][:define].call(:initialize) do |instance_scope, capacity=20|
instance_scope[:instance_vars]['@capacity'] = capacity
instance_scope[:instance_vars]['@bikes'] = []
end
class_scope[:methods][:define].call(:bikes) do |instance_scope|
instance_scope[:instance_vars]['@bikes']
end
class_scope[:methods][:define].call(:dock) do |instance_scope, bike|
instance_scope[:instance_vars]['@bikes'] << bike
end
class_scope[:methods][:define].call(:release_bike) do |instance_scope|
instance_scope[:instance_vars]['@bikes'].pop
end
end
-----