mirror of
https://github.com/kikito/middleclass.git
synced 2024-11-08 09:34:22 +00:00
restores :allocate and adds more documentation
This commit is contained in:
parent
4789a39d14
commit
958cae6c1c
@ -7,7 +7,6 @@ Version 4.0.0
|
|||||||
* Added the capacity of setting up the `__index` metamethod in classes
|
* Added the capacity of setting up the `__index` metamethod in classes
|
||||||
* Removed global `Object` (classes created with `class(<name>)` have no superclass now)
|
* Removed global `Object` (classes created with `class(<name>)` have no superclass now)
|
||||||
* Removed default method `Class:implements(<mixin>)`
|
* Removed default method `Class:implements(<mixin>)`
|
||||||
* Removed default method `Class:allocate`
|
|
||||||
* Renamed several internal functions
|
* Renamed several internal functions
|
||||||
|
|
||||||
Version 3.2.0
|
Version 3.2.0
|
||||||
|
52
README.md
52
README.md
@ -40,6 +40,10 @@ Documentation
|
|||||||
|
|
||||||
See the [github wiki page](https://github.com/kikito/middleclass/wiki) for examples & documentation.
|
See the [github wiki page](https://github.com/kikito/middleclass/wiki) for examples & documentation.
|
||||||
|
|
||||||
|
You can read the `CHANGELOG.md` file to see what has changed on each version of this library.
|
||||||
|
|
||||||
|
If you need help updating to a new middleclass version, read `UPDATING.md`.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
@ -73,52 +77,4 @@ License
|
|||||||
|
|
||||||
Middleclass is distributed under the MIT license.
|
Middleclass is distributed under the MIT license.
|
||||||
|
|
||||||
Updating from 2.x
|
|
||||||
=================
|
|
||||||
|
|
||||||
Middleclass used to expose several global variables on the main scope. It does not do that anymore.
|
|
||||||
|
|
||||||
`class` is now returned by `require 'middleclass'`, and it is not set globally. So you can do this:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local class = require 'middleclass'
|
|
||||||
local MyClass = class('MyClass') -- works as before
|
|
||||||
```
|
|
||||||
|
|
||||||
`Object` is not a global variable any more. But you can get it from `class.Object`
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local class = require 'middleclass'
|
|
||||||
local Object = class.Object
|
|
||||||
|
|
||||||
print(Object) -- prints 'class Object'
|
|
||||||
```
|
|
||||||
|
|
||||||
The public functions `instanceOf`, `subclassOf` and `includes` have been replaced by `Object.isInstanceOf`, `Object.static.isSubclassOf` and `Object.static.includes`.
|
|
||||||
|
|
||||||
Prior to 3.x:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
instanceOf(MyClass, obj)
|
|
||||||
subclassOf(Object, aClass)
|
|
||||||
includes(aMixin, aClass)
|
|
||||||
```
|
|
||||||
|
|
||||||
Since 3.x:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
obj:isInstanceOf(MyClass)
|
|
||||||
aClass:isSubclassOf(Object)
|
|
||||||
aClass:includes(aMixin)
|
|
||||||
```
|
|
||||||
|
|
||||||
The 3.x code snippet will throw an error if `obj` is not an object, or if `aClass` is not a class (since they will not implement `isInstanceOf`, `isSubclassOf` or `includes`).
|
|
||||||
If you are unsure of whether `obj` and `aClass` are an object or a class, you can use the methods in `Object`. They are prepared to work with random types, not just classes and instances:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
Object.isInstanceOf(obj, MyClass)
|
|
||||||
Object.isSubclassOf(aClass, Object)
|
|
||||||
Object.includes(aClass, aMixin)
|
|
||||||
```
|
|
||||||
|
|
||||||
Notice that the parameter order is not the same now as it was in 2.x. Also note the change in naming: `isInstanceOf` instead of `instanceOf`, and `isSubclassOf` instead of `subclassOf`.
|
|
||||||
|
69
UPDATING.md
Normal file
69
UPDATING.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
Updating from 3.x to 4.x
|
||||||
|
========================
|
||||||
|
|
||||||
|
In middleclass 4.0 there is no global `Object` class any more. Classes created with `class(<name>)` don't have a superclass any more.
|
||||||
|
If you need a global `Object` class, you must create it explicitly and then use it when creating new classes:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local Object = class('Object')
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
local MyClass = class('MyClass', Object)
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using a library which depends on the internal implementation of middleclass (for example, [stateful.lua](https://github.com/kikito/stateful.lua) they might not work with middleclass 4.0. You might need to update those other libraries.
|
||||||
|
|
||||||
|
Middleclass 4.0 comes with support for `__index` metamethod support. If your library manipulated the classes' `__instanceDict` internal attribute, you might do the same thing now using `__index` instead.
|
||||||
|
|
||||||
|
Also note that the class method `:implements` has been removed.
|
||||||
|
|
||||||
|
Updating from 2.x to 3.x
|
||||||
|
========================
|
||||||
|
|
||||||
|
Middleclass used to expose several global variables on the main scope. It does not do that anymore.
|
||||||
|
|
||||||
|
`class` is now returned by `require 'middleclass'`, and it is not set globally. So you can do this:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local class = require 'middleclass'
|
||||||
|
local MyClass = class('MyClass') -- works as before
|
||||||
|
```
|
||||||
|
|
||||||
|
`Object` is not a global variable any more. But you can get it from `class.Object`
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local class = require 'middleclass'
|
||||||
|
local Object = class.Object
|
||||||
|
|
||||||
|
print(Object) -- prints 'class Object'
|
||||||
|
```
|
||||||
|
|
||||||
|
The public functions `instanceOf`, `subclassOf` and `includes` have been replaced by `Object.isInstanceOf`, `Object.static.isSubclassOf` and `Object.static.includes`.
|
||||||
|
|
||||||
|
Prior to 3.x:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
instanceOf(MyClass, obj)
|
||||||
|
subclassOf(Object, aClass)
|
||||||
|
includes(aMixin, aClass)
|
||||||
|
```
|
||||||
|
|
||||||
|
Since 3.x:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
obj:isInstanceOf(MyClass)
|
||||||
|
aClass:isSubclassOf(Object)
|
||||||
|
aClass:includes(aMixin)
|
||||||
|
```
|
||||||
|
|
||||||
|
The 3.x code snippet will throw an error if `obj` is not an object, or if `aClass` is not a class (since they will not implement `isInstanceOf`, `isSubclassOf` or `includes`).
|
||||||
|
If you are unsure of whether `obj` and `aClass` are an object or a class, you can use the methods in `Object`. They are prepared to work with random types, not just classes and instances:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
Object.isInstanceOf(obj, MyClass)
|
||||||
|
Object.isSubclassOf(aClass, Object)
|
||||||
|
Object.includes(aClass, aMixin)
|
||||||
|
```
|
||||||
|
|
||||||
|
Notice that the parameter order is not the same now as it was in 2.x. Also note the change in naming: `isInstanceOf` instead of `instanceOf`, and `isSubclassOf` instead of `subclassOf`.
|
@ -121,10 +121,14 @@ local DefaultMixin = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
static = {
|
static = {
|
||||||
|
allocate = function(self)
|
||||||
|
assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
|
||||||
|
return setmetatable({ class = self }, self.__instanceDict)
|
||||||
|
end,
|
||||||
|
|
||||||
new = function(self, ...)
|
new = function(self, ...)
|
||||||
assert(type(self) == 'table', "Make sure that you are using 'Class:new' instead of 'Class.new'")
|
assert(type(self) == 'table', "Make sure that you are using 'Class:new' instead of 'Class.new'")
|
||||||
local instance = setmetatable({ class = self }, self.__instanceDict)
|
local instance = self:allocate()
|
||||||
instance:initialize(...)
|
instance:initialize(...)
|
||||||
return instance
|
return instance
|
||||||
end,
|
end,
|
||||||
|
@ -68,6 +68,39 @@ describe('Default methods', function()
|
|||||||
function SubClass:initialize() self.mark=true end
|
function SubClass:initialize() self.mark=true end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('allocate', function()
|
||||||
|
|
||||||
|
it('allocates instances properly', function()
|
||||||
|
local instance = SubClass:allocate()
|
||||||
|
assert.equal(instance.class, SubClass)
|
||||||
|
assert.equal(tostring(instance), "instance of " .. tostring(SubClass))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('throws an error when used without the :', function()
|
||||||
|
assert.error(Object.allocate)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('does not call the initializer', function()
|
||||||
|
local allocated = SubClass:allocate()
|
||||||
|
assert.is_nil(allocated.mark)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('can be overriden', function()
|
||||||
|
|
||||||
|
local previousAllocate = SubClass.static.allocate
|
||||||
|
|
||||||
|
function SubClass.static:allocate()
|
||||||
|
local instance = previousAllocate(SubClass)
|
||||||
|
instance.mark = true
|
||||||
|
return instance
|
||||||
|
end
|
||||||
|
|
||||||
|
local allocated = SubClass:allocate()
|
||||||
|
assert.is_true(allocated.mark)
|
||||||
|
end)
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
describe('new', function()
|
describe('new', function()
|
||||||
|
|
||||||
it('initializes instances properly', function()
|
it('initializes instances properly', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user