restores :allocate and adds more documentation

This commit is contained in:
kikito 2015-12-31 00:47:37 +01:00
parent 4789a39d14
commit 958cae6c1c
5 changed files with 112 additions and 51 deletions

View File

@ -7,7 +7,6 @@ Version 4.0.0
* Added the capacity of setting up the `__index` metamethod in classes
* Removed global `Object` (classes created with `class(<name>)` have no superclass now)
* Removed default method `Class:implements(<mixin>)`
* Removed default method `Class:allocate`
* Renamed several internal functions
Version 3.2.0

View File

@ -40,6 +40,10 @@ 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
============
@ -73,52 +77,4 @@ 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
View 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`.

View File

@ -121,10 +121,14 @@ local DefaultMixin = {
end,
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, ...)
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(...)
return instance
end,

View File

@ -68,7 +68,40 @@ describe('Default methods', function()
function SubClass:initialize() self.mark=true end
end)
describe('new', function()
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()
it('initializes instances properly', function()
local instance = SubClass:new()