Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stevedonovan/Penlight.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorsteve donovan <steve.j.donovan@gmail.com>2012-03-25 20:30:34 +0400
committersteve donovan <steve.j.donovan@gmail.com>2012-03-25 20:30:34 +0400
commitca74c95c5975958d7195490e9f87d3d981d617ae (patch)
tree7ac05244555be9ad90ca3b7d452e70e910875c6d /docs
parentb302d749512a4a4e7dbfd2cfbbae0028e6dcb7af (diff)
property support for classes and doc updates
Diffstat (limited to 'docs')
-rw-r--r--docs/manual/01-introduction.md34
-rw-r--r--docs/manual/02-arrays.md13
2 files changed, 41 insertions, 6 deletions
diff --git a/docs/manual/01-introduction.md b/docs/manual/01-introduction.md
index 1604f18..bdd0c56 100644
--- a/docs/manual/01-introduction.md
+++ b/docs/manual/01-introduction.md
@@ -258,3 +258,37 @@ This useful notation is borrowed from Hugo Etchegoyen's [classlib](http://lua-us
Penlight provides a number of useful classes; there is `List`, which is a Lua clone of the standard Python list object, and `Set` which represents sets. There are three kinds of _map_ defined: `Map`, `MultiMap` (where a key may have multiple values) and `OrderedMap` (where the order of insertion is remembered.). There is nothing special about these classes and you may inherit from them.
+_Properties_ are a useful object-oriented pattern. We wish to control access to a field, but don't wish to force the user of the class to say `obj:get_field()` etc. This excerpt from `tests/test-class.lua` shows how it is done:
+
+
+ local MyProps = class(class.properties)
+ local setted_a, got_b
+
+ function MyProps:_init ()
+ self._a = 1
+ self._b = 2
+ end
+
+ function MyProps:set_a (v)
+ setted_a = true
+ self._a = v
+ end
+
+ function MyProps:get_b ()
+ got_b = true
+ return self._b
+ end
+
+ local mp = MyProps()
+
+ mp.a = 10
+
+ asserteq(mp.a,10)
+ asserteq(mp.b,2)
+ asserteq(setted_a and got_b, true)
+
+The convention is that the internal field name is prefixed with an underscore; when reading `mp.a`, first a check for an explicit _getter_ `get_a` and then only look for `_a`. Simularly, writing `mp.a` causes the _setter_ `set_a` to be used.
+
+This is cool behaviour, but like much Lua metaprogramming, it is not free. Method lookup on such objects goes through `__index` as before, but now `__index` is a function which has to explicitly look up methods in the class, before doing any property indexing, which is not going to be as fast as field lookup. If however, your accessors actually do non-trivial things, then the extra overhead could be worth it.
+
+This is not really intended for _access control_ because external code can write to `mp._a` directly. It is possible to have this kind of control in Lua, but it again comes with run-time costs, and in this case a simple audit of code will reveal any naughty use of 'protected' fields.
diff --git a/docs/manual/02-arrays.md b/docs/manual/02-arrays.md
index ed63d88..8241e3e 100644
--- a/docs/manual/02-arrays.md
+++ b/docs/manual/02-arrays.md
@@ -112,7 +112,11 @@ When querying the value of a `Map`, it is best to use the `get` method:
The reason is that `m[key]` can be ambiguous; due to the current implementation, `m["get"]` will always succeed, because if a value is not present in the map, it will be looked up in the `Map` metatable, which contains a method `get`. There is currently no simple solution to this annoying restriction.
-A `Set` is a special kind of `Map`, where all the values are `true`. So `get` will always return either `true` or `nil`; all the values are keys, and the order is not important. So in this case `values` is defined to return a list of the keys. Sets can display themselves, and the basic operations like `union` (`+`) and `intersection` (`*`) are defined.
+There are some useful classes which inherit from `Map`. An `OrderedMap` behaves like a `Map` but keeps its keys in order if you use its `set` method to add keys and values. Like all the 'container' classes in Penlight, it defines an `iter` method for iterating over its values; this will return the keys and values in the order of insertion; the `keys` and `values` methods likewise.
+
+A `MultiMap` allows multiple values to be associated with a given key. So `set` (as before) takes a key and a value, but calling it with the same key and a different value does not overwrite but adds a new value. `get` (or using `[]`) will return a list of values.
+
+A `Set` can be seen as a special kind of `Map`, where all the values are `true`, the keys are the values, and the order is not important. So in this case `Set.values` is defined to return a list of the keys. Sets can display themselves, and the basic operations like `union` (`+`) and `intersection` (`*`) are defined.
> Set = require 'pl.Set'
> = Set{'one','two'} == Set{'two','one'}
@@ -132,18 +136,15 @@ A `Set` is a special kind of `Map`, where all the values are `true`. So `get` wi
> = fruit*colours
[orange]
-There are also the methods `difference` and `symmetric_difference`. The first answers the question 'what fruits are not colours?' and the second 'what are fruits and colours but not both?'
+There are also the functions `Set.difference` and `Set.symmetric_difference`. The first answers the question 'what fruits are not colours?' and the second 'what are fruits and colours but not both?'
> = fruit - colours
[apple,banana]
> = fruit ^ colours
[blue,green,apple,red,banana]
-Adding elements to a set is either done like `fruit['peach'] = true` or by `fruit:set('peach')`. Removing is either `fruit['apple'] = nil` or `fruit:unset('apple')`.
+Adding elements to a set is simply `fruit['peach'] = true` and removing is `fruit['apple'] = nil` . To make this simplicity properly, the `Set` class has no methods - either you use the operator forms or explicitly use `Set.intersect` etc. In this way we avoid the ambiguity that plagues `Map`.
-There are also some useful classes which also inherit from `Map`. An `OrderedMap` behaves like a `Map` but keeps its keys in order if you use its `set` method to add keys and values. Like all the 'container' classes in Penlight, it defines an `iter` method for iterating over its values; this will return the keys and values in the order of insertion; the `keys` and `values` methods likewise.
-
-A `MultiMap` allows multiple values to be associated with a given key. So `set` (as before) takes a key and a value, but calling it with the same key and a different value does not overwrite but adds a new value. `get` (or using `[]`) will return a list of values.
(See `pl.Map` and `pl.Set`)