/**
* Dictionary.js - JavaScript OO Implementation of Dictionary Data Structure
*/
/**
* @class
* A Dictionary stores an unordered collection of data as key/value pairs,
* known as entries. Dictionary keys are unique; the association of keys
* and values defines a mapping. Dictionaries are also known as associative arrays
* or maps. A Dictionary ADT includes the following operations:
*

*
getSize - to get the size of the data structure;

*
isEmpty - to check to see if it is empty;

*
put - to put or add new entries to the dictionary;

*
get - to get the value associated with a given key;

*
remove - to remove entries from the dictionary;

*
getEntries - to get all entries in the dictionary
* (as an iterable or iterator);

*
getValues - to get all values in the dictionary;

*
getKeys - to get all keys in the dictionary;
 and
*
toString - to represent the entries in the dictionary
* as a string and/or to display the contents of the dictionary.
*

* Most modern browsers support Maps (associative arrays/dictionaries),
* so this implementation isn't strictly necessary. If you choose to
* use this implementation, note that it depends on the Iter.js class
* to work. You may wish to use requirejs to manage module loading in
* your application and handle the relationship that way. But the
* simplest way to use the Dictionary class is to make sure to include
* the Iter.js script in the html before the Dictionary.js script.
*/
var Dictionary = (function() {
/**
* @constructor
* @description Create and initialise new Dictionary object
*/
function Dictionary() {
// Objects have prototypes so there are 'default' keys
// Since ES5, this problem can be mitigated by using Object.create(null)
// See MDN on Maps at: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
this.table = Object.create(null);
}
/**
* @memberOf Dictionary
* @instance
* @method put
* @description Add (put) an entry to the dictionary.
* @param {String} key a string representing the key for the given entry
* @param {*} val any value representing the value for the given entry
* @return {number} 1 if successful, -1 if unsuccessful
*/
Dictionary.prototype.put = function(key, val) {
// If a key/val pair have been supplied, the key is unique and the key is not a number,
// add the entry to the dictionary and return 1 for success
if(!(key in this.table) && (key != undefined, val != undefined) && typeof key != "number")
{
this.table[key] = val;
return 1;
// else return -1 to signify that the operation was unsuccessful
} else {
return -1;
}
};
/**
* @memberOf Dictionary
* @instance
* @method get
* @description Get the value associated with the given key in the dictionary.
* @param {String} key The key to the associated value in the dictionary
* @return {*} The value associated with the given key or undefined if the key is not in the dictionary
*/
Dictionary.prototype.get = function(key) {
return this.table[key];
};
/**
* @memberOf Dictionary
* @instance
* @method remove
* @description Remove the entry corresponding to the given key.
* @param {string} key The key that identifies the entry to be removed from the dictionary
* @return {number} 1 if the operation was successful, -1 otherwise
*/
Dictionary.prototype.remove = function(key) {
if(key in this.table)
{
delete this.table[key];
return 1;
}
else {
return -1;
}
};
/**
* @memberOf Dictionary
* @instance
* @method getKeys
* @description Get an iterable (array) of all keys stored in the dictionary.
* @return {array} Array of dictionary keys or an empty array
*/
Dictionary.prototype.getKeys = function() {
return Object.keys(this.table);
};
/**
* @memberOf Dictionary
* @instance
* @method getValues
* @description Get an iterable (array) of all values stored in the dictionary.
* @return {array} Array of dictionary values
*/
Dictionary.prototype.getValues = function() {
// Object.values' specification is not stablised and may not work in certain versions of Chrome
// and other browsers see:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values#Browser_compatibility
var keys = Object.keys(this.table);
var outArr = [];
for(key in this.table) {
outArr.push(this.table[key]);
}
return outArr;
};
/**
* @memberOf Dictionary
* @instance
* @method getEntries
* @description Get an iterator of all entries in the dictionary.
* @return {Iter} A new iterator on the current dictionary
*/
Dictionary.prototype.getEntries = function() {
return new Iter(this.table) || undefined;
};
/**
* @memberOf Dictionary
* @instance
* @method getSize
* @description Get the dictionary size (number of entries).
* @return {number} The number of entries in the dictionary
*/
Dictionary.prototype.getSize = function() {
return Object.keys(this.table).length;
};
/**
* @memberOf Dictionary
* @instance
* @method isEmpty
* @description Check whether dictionary is empty or not.
* @return {boolean} True if dictionary is empty, false otherwise
*/
Dictionary.prototype.isEmpty = function() {
if(Object.keys(this.table).length === 0){
return true;
}
else {
return false;
}
};
/**
* @memberOf Iter
* @instance
* @method clear
* @description Clear or empty the dictionary.
*/
Dictionary.prototype.clear = function() {
var keys = Object.keys(this.table);
var key;
for(key in keys) {
delete this.table[keys[key]];
}
};
/**
* @memberOf Dictionary
* @instance
* @method toString
* @description Get a key-sorted string representation of the dictionary.
* @return {string} A key-sorted string representation of the dictionary
*/
Dictionary.prototype.toString = function() {
var outStr = "";
var key;
var keys = Object.keys(this.table).sort();
for(key in keys) {
outStr += keys[key] + ": " + this.table[keys[key]] + ", ";
}
return outStr.slice(0, -2); // trim the last comma and space and return to caller
};
/** Auxiliary Functions */
return Dictionary;
}());


please write your height and then weight (cm and kg):
remember now weight:
Choose background gradient color 1:
Choose background gradient color 2:
Calculate a factorial lol


Rhodeside Harwell is thrilled to announce the promotion of five new Associate Principals – Derrick Wolbaum, Drew Taylor, Jennifer Koch, Rebecca May, and Sukirti Ghosh.
With decades of combined experience covering countless sectors and cities, they’ve all grown together at the firm and are poised to keep RHI at the forefront of landscape architecture, planning, and urban design.
As we reflect on an unprecedented year, Rhodeside Harwell is proud to celebrate our 35th anniversary. Our firm continues to set the standard for landscape architecture, planning, and urban design, creating successful and meaningful places locally, nationally, and around the world.
RHODESIDE HARWELL
LANDSCAPE ARCHITECTURE / PLANNING / URBAN DESIGN
Washington DC
510 King Street, Ste. 300
Alexandria, VA 22314
703-683-7447
New York City
347 W. 36th St, Ste. 1201
New York, NY 10018
212-216-0055


Nehemiah 11:9
And Joel the son of Zichri was their overseer: and Judah the son of Senuah was second over the city.


SuperCop
Jackie Chan does all his stunts. That's something hard to say about action "heroes" lately who rely on stunt doubles. SuperCop is actually the third film in the Police Story series. But, that does not make it a requirement to see the first two before seeing SuperCop. SuperCop is a self-contained film.
Jackie plays Kevin Chan, a supercop in Hong Kong. He is talked into a mission to stop a large drug lord in Hong Kong. But the assignment first takes him to China, where he meets the Chief of Security, played by Michelle Khan. The story, though flimsy, is not what one would go to see at a Jackie Chan film.  And it is not just action, there is comedy interleaved in the action too, to relieve tension.
There are two hugely memorable action sequences in SuperCop. One takes place in a drug lord's camp and the other takes place in Malaysia. The one in Malaysia has Jackie hanging from a rope ladder, which is attached to a helicopter flying over the city of Kuala Lumpur.
Another different sequence shows off the humor that Jackie performs. And this is in the earlier portion of the film at a Chinese Special Forces Training Camp.
Jackie shows that it is possible for an action hero to be brave enough to do their own stunts, be funny, and likeable.
SuperCop is pure action and should be seen. Don't leave after the movie finishes at the end of ever Jackie Chan movie there are outtakes and SuperCop is no different. There are more laughs in the outtakes than there are in a good sitcom. You can also see how dangerous the stunts get. It's not a Jackie fikm unless there is someone being taking away in a stretcher. And after you watch SuperCop, see First Strike, whish is Police Story 4.
Copyright 1997 Steve Kong -- steve kong<EMAIL_ADDRESS>spy on me at: http://mookie.relay.net/mookie/steve-cam.html
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


| Aliases: | |
|---|---|
| ID: | {{element['id']}} |
Did you mean to search for a structure match by SMILES string? Try a structure search.
Often, this happens if the inputted structure is too complicated (contains too many terms separated by spaces or special characters). Consider deleting some words, or enclose the search in double quotes (e.g. "tyrosine kinase inhibitor")
Please try again and if it persists, email help@reframedb.org


| 017:099 Khan | : |
See they not that Allah, Who created the heavens and the earth, is Able to create the like of them. And He has decreed for them an appointed term, whereof there is not doubt. But the Zalimun (polytheists and wrong-doers, etc.) refuse (the truth the Message of Islamic Monotheism, and accept nothing) but disbelief. |
| 017:099 Maulana | : |
See they not that Allah, Who created the heavens and the earth, is able to create the like of them? And He has appointed for them a term, whereof there is no doubt. But the wrongdoers consent to naught but denying. |
| 017:099 Pickthal | : |
Have they not seen that Allah Who created the heavens and the earth is Able to create the like of them, and hath appointed for them an end whereof there is no doubt? But the wrong-doers refuse aught save disbelief. |
| 017:099 Rashad | : |
Could they not see that the GOD who created the heavens and the earth is able to create the same creations? (That) He has predetermined for them an irrevocable life span? Yet, the disbelievers insist upon disbelieving. |
| 017:099 Sarwar | : |
Do they not realize that God, who has created the heavens and the earth, has the power to create their like? He has given them life for an appointed time of which there is no doubt. The unjust turn away in disbelief (from Our revelation). |
| 017:099 Shakir | : |
Do they not consider that Allah, Who created the heavens and the earth, is able to create their like, and He has appointed for them a doom about which there is no doubt? But the unjust do not consent to aught but denying. |
| 017:099 Sherali | : |
Do they not see that ALLAH, WHO created the heavens and the earth, has the power to create the like of them? And HE has appointed for them a term; there is no doubt about it. But the wrongdoers would reject everything but disbelief. |
| 017:099 Yusufali | : |
See they not that Allah, Who created the heavens and the earth, has power to create the like of them (anew)? Only He has decreed a term appointed, of which there is no doubt. But the unjust refuse (to receive it) except with ingratitude. |
Concepts/Themes Covered: أركان الإسلام > التوحيد > توحيد الله تعالي > صفات الله تعالى > القادر Pillars of Islam> Islamic> Oneness of Allah> His Glory's Characteristics> The Able
This tool uses eight English parallel translations for the Holy Quran imported from Mr. Clay Smith. You can also visit Qurany Concepts for browsing the Quran themes or topics. If you want to search the Holy Quran for keywords, please visit Qurany Keywords.


{include file="public/css" /} {include file="public/js" /}
{include file="public/header1" /} {include file="public/header2" /}
{include file="public/menu_r" /}
首页
管理营销
待付款项目
{empty name="$company"}
{$me.nick_name}
{:getUserLevel($me.user_rank,2)}
{:getUserLevel($me.user_rank,1)}
创建企业
加入企业
{else/}
{$company.company_name}
{/empty}
{include file="company/_left" /}
收款详情
{if condition="$info.bill_type==1"} {include file="company/income_details_4" /} {elseif condition="$info.bill_type==2"} {include file="company/income_details_3" /} {elseif condition="$info.bill_type==3"} {include file="company/income_details_2" /} {else/} {include file="company/income_details_1" /} {/if}
{include file="public/footer1" /} {include file="public/footer2" /} {include file="public/js_1" /}


tostring_set(3f) - [M_display] set modes for TOSTRING(3f)
Description
Examples
Author
The subroutine TOSTRING_SET has five arguments, all of which are optional. Argument association will normally be realized using argument keywords, e.g. CALL TOSTRING_SET(SEP=; ). The examples in section 5.4 clarify how to use this subroutine. The five arguments are:
SEP Character string used to separate elements of displayed vectors. Original default value is RFMT Character string containing default edit descriptor to use to display real items. The original default value is 1PG12.5 IFMT Character string containing default edit descriptor to use to display integer items. The original default value is I0. TRIMB Controls whether leading and trailing blanks are trimmed from individual displayed elements. Possible values are YES (to trim blanks) and NO (for no trimming). Default is YES. TRIMZ Controls whether trailing zeros are trimmed from the fractional part of displayed items. Possible values are NONE (for no zero trimming), G (to trim fractional trailing zeros only when G editing is used), and ALL (to trim zeros with all types of editing). Trailing decimal points are also removed when zero-trimming is active. Default value is G.
When the original (factory) defaults are in effect, the result of invoking TOSTRING will usually be as follows.
Invocation Returned String ---------- --------------- tostring(atan(1.0)) 0.785398 tostring(exp([-3.,-1.,0.,1.])) 4.97871E-02, 0.36788, 1, 2.7183 tostring(real([(i,i=1,5)])**8) 1, 256, 6561, 65536, 3.90625E+05 tostring([1.23456,1.2300,1.23456e6]) 1.2346, 1.23, 1.23456E+06 tostring(real([(i,i=1,5)])**8,f0.1) 1.0, 256.0, 6561.0, 65536.0, 390625.0 tostring(real([(i,i=1,5)])**8,f6.1) 1.0, 256.0, 6561.0, ******, ****** tostring([1200000.,-1.2e-9]) 1.2E+06, -1.2E-09 ! tostring(1.200d103) 1.2+103 tostring([1.1d0,2.2d10,3.3d20]) 1.1E+00, 2.2E+10, 3.3E+20 ! tostring(-77) -77 tostring([(i,i=-3,3)]**11) -177147, -2048, -1, 0, 1, 2048, 177147 tostring([(i,i=-3,3)]**11, i7) -177147, -2048, -1, 0, 1, 2048, 177147 tostring([(i,i=-3,3)]**11, i4) ****, ****, -1, 0, 1, 2048, **** ! tostring((1,3)/(4,2)) 0.5 + 0.5i tostring(cmplx([-1,-2])**0.25) 0.70711 + 0.70711i, 0.8409 + 0.8409i ! tostring([.true., .false., .false.]) T, F, F tostring(.true., L2) TThe returned strings may be slightly different from the ones shown, because some compilers (at least some versions of g95) will produce one more decimal place in a few cases, and because the Fortran standard allows G editing to give exponent fields in the form 0dd instead of Edd. The examples make use of brackets to construct vector constants (a Fortran 2003 feature). If the compiler being used does not support this, [ and ] must be used instead. Notice that trimming is on by default so there is not much purpose in specifying the format for integers and logicals. Notice also that (usually) 5 significant digits are displayed when the default G editing results in F edited output, but 6 digits for the numbers of small or large magnitude, displayed with E editing. This discrepancy is present in the Fortran standard; the presence of the scale factor 1P in the edit descriptor increases the number of displayed significant digits.
Examples of using TOSTRING_SET follow (again the returned string may be slightly different).
 Version number 1.02 6-Sept-2008, Kristjan Jonasson, Dept. of Computer Science, University of Iceland (jonasson@hi.is).
| Nemo Release 3.1 | tostring_set (3) | July 22, 2023 |


mesg - control write access to your terminal
mesg
Mesg controls the access to your terminal by others. It's typically used to allow or disallow other users to write to your terminal (see write(1)).
Allow write access to your terminal.
Disallow write access to your terminal.
If no option is given, mesg prints out the current access state of your terminal.
Mesg assumes that its standard input is connected to your terminal. That also means that if you are logged in multiple times, you can get/set the mesg status of other sessions by using redirection. For example "mesg n < /dev/pts/46".
Miquel van Smoorenburg<EMAIL_ADDRESS>talk (1), write (1), wall (1)


Karl G. wrote:By the way, as I was doing my taxes this year, I discovered that if donations reach > $400 this venture becomes a business, and I have to pay 15% tax on it and start registering for trademarks and stuff, which incurs even more expense ($275!!!). So I guess if we get more than $400 things are going to get pretty interesting around here...but we'll get there when we get there. Let's finish this game first
ila.org wrote:Not all not-for-profit organizations qualify for a tax exemption. For instance, the American Heart Association is a not-for-profit corporation which would also qualify for federal tax exemption. On the other hand, a neighborhood homeowners' association is also not-for-profit but would not qualify for a tax break. Only certain kinds of not-for-profit organizations--charities, schools, churches, clubs, etc.--fall into the tax exempt category.
Users browsing this forum: No registered users and 1 guest


Once Upon A Time...
Great stories aren’t just told, they are experienced. At the heart of all litigation is a message. That message, when told well, becomes an easily followed road map to a story. When told with the assistance of Visual Law, it becomes unforgettable. Our unique style, resources and expertise can transform any litigation, whether it is trial, mediation, settlement conference, arbitration or hearing, into a more meaningful and most memorable experience.
- Forensic Mapping
- Forensic A.M.
- Strategy Consulting
- Trial Technology
- Settlment Documentaries


Patrick Mahomes throws unreal jump pass for TD to Mecole Hardman (Video)
by TSD StaffChiefs quarterback Patrick Mahomes has shown that he can make unbelievable plays using a variety of different arm angles, and footwork as well.
As a former baseball player, like Russell Wilson, he can make plays that few other signal-callers can.
He showed that during Sunday’s game against the Titans, making Tennessee pay on a pivotal play that extended the Chiefs’ lead to two scores. Mahomes sensed the pressure, but still managed to jump up in the pocket and threw a dime touchdown pass to Mecole Hardman for the 63-yard touchdown.
Jump-pass TD, wow.


McArdles
48 Arch Street
Greenwich, CT
on the web at www.mcardles.com
Sickles Market
Harrison Avenue
Little Silver, New Jersey
on the web at www.sicklesmarket.com
Martin Viette Nursery
Route 25A
East Norwich, NY 11732
on the web at www.martinviettenurseries.com
Hicks Nursery
100 Jericho Turnpike
Westbury, NY 11590
on the web at www.hicksnursery.com
Atlantic Nursery
Atlantic Avenue
Freeport, NY 11532
on the web at www.Atlanticnursery.com
Marders
Snakehollow Road
Bridgehampton, NY 11932
on the web at www.marders.com


Reports method parameters that are named identically to the visible fields of the method's class
or surrounding classes if it is a parameter inside of an inner or anonymous class.
Such a parameter name may be confusing.
The quick-fix is suggested to rename the parameter.
Example:
class Main {
private final int value;
public Main(int value) {
this.value = value;
}
}
Use the "Options" panel below to configure the inspection:
- Enable the first checkbox to ignore parameters of simple setters.
- Enable the second checkbox to ignore for private fields in a superclass, which are not visible from the parameter.
- Enable the third checkbox to ignore parameters of constructors.
- Enable the fourth checkbox to ignore parameters of abstract methods.
-
Enable the fifth checkbox to ignore parameters of
static
methods hiding an instance field and
to ignore parameters of instance methods in static inner classes hiding an instance field in an outer class.
While not strictly hiding, such parameters can still be confusing.


This widget displays a streaming graph of the number of edits to a given language's Wikipedia over time. The language and time frame can be adjusted in the widget's settings.


| Author: | Daniel Wallin, Arvid Norberg |
|---|---|
| Copyright: | Copyright Daniel Wallin, Arvid Norberg 2003. |
| License: | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
Contents
Luabind is a library that helps you create bindings between C++ and Lua. It has the ability to expose functions and classes, written in C++, to Lua. It will also supply the functionality to define classes in Lua and let them derive from other Lua classes or C++ classes. Lua classes can override virtual functions from their C++ base classes. It is written towards Lua 5.0, and does not work with Lua 4.
It is implemented utilizing template meta programming. That means that you don't need an extra preprocess pass to compile your project (it is done by the compiler). It also means you don't (usually) have to know the exact signature of each function you register, since the library will generate code depending on the compile-time type of the function (which includes the signature). The main drawback of this approach is that the compilation time will increase for the file that does the registration, it is therefore recommended that you register everything in the same cpp-file.
Luabind is released under the terms of the MIT license.
We are very interested in hearing about projects that use luabind, please let us know about your project.
The main channel for help and feedback is the luabind mailing list. There's also an IRC channel #luabind on irc.freenode.net.
Luabind supports:
- Overloaded free functions
- C++ classes in Lua
- Overloaded member functions
- Operators
- Properties
- Enums
- Lua functions in C++
- Lua classes in C++
- Lua classes (single inheritance)
- Derives from Lua or C++ classes
- Override virtual functions from C++ classes
- Implicit casts between registered types
- Best match signature matching
- Return value policies and parameter policies
Luabind has been tested to work on the following compilers:
- Visual Studio 7.1
- Intel C++ 6.0 (Windows)
- GCC 2.95.3 (cygwin)
- GCC 3.0.4 (Debian/Linux)
- GCC 3.1 (SunOS 5.8)
- GCC 3.2 (cygwin)
- GCC 3.3.1 (cygwin)
- GCC 3.3 (Apple, MacOS X)
- GCC 4.0 (Apple, MacOS X)
It has been confirmed not to work with:
- GCC 2.95.2 (SunOS 5.8)
Metrowerks 8.3 (Windows) compiles but fails the const-test. This means that const member functions are treated as non-const member functions.
If you have tried luabind with a compiler not listed here, let us know your result with it.
Luabind depends on a number of Boost 1.34 libraries. It also depends on Boost Jam and Boost Build V2 to build the library and run the tests. Boost provides precompiled bjam binaries for a number of platforms. If there isn't a precompiled binary available for your platform, you may need to build it yourself.
The environment varaible LUA_PATH needs to be set to point to a directory containing the Lua include directory and built libraries. At least for the purpose of running the test suite, the recommended way to get these is the Lua Binaries Windows x86 DLL and Includes package.
Furthermore, the environment variable BOOST_ROOT must point to a Boost installation directory.
If your system already has Lua installed, it is very likely that the build system will automatically find it and just work. If you have Lua installed in a non-standard location, you may need to set LUA_PATH to point to the installation prefix.
BOOST_ROOT can be set to a Boost installation directory. If left unset, the build system will try to use boost headers from the standard include path.
If you have both the 10.4 and 10.5 SDK installed, Boost Build seems to default to 10.4. Lua, at least when installed from MacPorts, will be linked with the 10.5 SDK. If the luabind build fails with link errors, you may need to explicitly build with the 10.5 SDK:
$ bjam macosx-version=10.5
Building the default variant of the library, which is a shared debug library, is simply done by invoking bjam in the luabind root directory:
$ bjam ...patience... ...found 714 targets... ...updating 23 targets...
When building with GCC on Linux, this results in:
bin/gcc-4.2.3/debug/libluabind.so
On Windows a dll and matching import library would be produced.
To run the unit tests, invoke bjam with the test target:
$ bjam test
This will build and run the unit tests in four different variants: debug, release, debug-static-lib, release-static-lib. A clean test run output should end with something like:
... updated xxx targets...
A failed run would end with something like:
...failed updating xxx target... ...skipped xxx targets...
If you are not using Boost Build to build your application, and want to use the shared library variant, LUABIND_DYNAMIC_LINK needs to be defined to properly import symbols.
To use luabind, you must include lua.h and luabind's main header file:
extern "C" { #include "lua.h" } #include <luabind/luabind.hpp>
This includes support for both registering classes and functions. If you just want to have support for functions or classes you can include luabind/function.hpp and luabind/class.hpp separately:
#include <luabind/function.hpp> #include <luabind/class.hpp>
The first thing you need to do is to call luabind::open(lua_State*) which will register the functions to create classes from Lua, and initialize some state-global structures used by luabind. If you don't call this function you will hit asserts later in the library. There is no corresponding close function because once a class has been registered in Lua, there really isn't any good way to remove it. Partly because any remaining instances of that class relies on the class being there. Everything will be cleaned up when the state is closed though.
Luabind's headers will never include lua.h directly, but through <luabind/lua_include.hpp>. If you for some reason need to include another Lua header, you can modify this file.
#include <iostream> #include <luabind/luabind.hpp> void greet() { std::cout << "hello world!\n"; } extern "C" int init(lua_State* L) { using namespace luabind; open(L); module(L) [ def("greet", &greet) ]; return 0; }
Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio > loadlib('hello_world.dll', 'init')() > greet() Hello world! >
Everything that gets registered in Lua is registered in a namespace (Lua tables) or in the global scope (called module). All registrations must be surrounded by its scope. To define a module, the luabind::module class is used. It is used like this:
module(L) [ // declarations ];
This will register all declared functions or classes in the global namespace in Lua. If you want to have a namespace for your module (like the standard libraries) you can give a name to the constructor, like this:
module(L, "my_library") [ // declarations ];
Here all declarations will be put in the my_library table.
If you want nested namespace's you can use the luabind::namespace_ class. It works exactly as luabind::module except that it doesn't take a lua_State* in it's constructor. An example of its usage could look like this:
module(L, "my_library") [ // declarations namespace_("detail") [ // library-private declarations ] ];
As you might have figured out, the following declarations are equivalent:
module(L) [ namespace_("my_library") [ // declarations ] ];
module(L, "my_library") [ // declarations ];
Each declaration must be separated by a comma, like this:
module(L) [ def("f", &f), def("g", &g), class_<A>("A") .def(constructor<int, int>), def("h", &h) ];
More about the actual declarations in the Binding functions to Lua and Binding classes to Lua sections.
A word of caution, if you are in really bad need for performance, putting your functions in tables will increase the lookup time.
To bind functions to Lua you use the function luabind::def(). It has the following synopsis:
template<class F, class policies> void def(const char* name, F f, const Policies&);
An example usage could be if you want to register the function float std::sin(float):
module(L) [ def("sin", &std::sin) ];
If you have more than one function with the same name, and want to register them in Lua, you have to explicitly give the signature. This is to let C++ know which function you refer to. For example, if you have two functions, int f(const char*) and void f(int).
module(L) [ def("f", (int(*)(const char*)) &f), def("f", (void(*)(int)) &f) ];
luabind will generate code that checks the Lua stack to see if the values there can match your functions' signatures. It will handle implicit typecasts between derived classes, and it will prefer matches with the least number of implicit casts. In a function call, if the function is overloaded and there's no overload that match the parameters better than the other, you have an ambiguity. This will spawn a run-time error, stating that the function call is ambiguous. A simple example of this is to register one function that takes an int and one that takes a float. Since Lua doesn't distinguish between floats and integers, both will always match.
Since all overloads are tested, it will always find the best match (not the first match). This also means that it can handle situations where the only difference in the signature is that one member function is const and the other isn't.
For example, if the following function and class is registered:
struct A { void f(); void f() const; }; const A* create_a(); struct B: A {}; struct C: B {}; void g(A*); void g(B*);
And the following Lua code is executed:
a1 = create_a() a1:f() -- the const version is called a2 = A() a2:f() -- the non-const version is called a = A() b = B() c = C() g(a) -- calls g(A*) g(b) -- calls g(B*) g(c) -- calls g(B*)
To call a Lua function, you can either use call_function() or an object.
template<class Ret> Ret call_function(lua_State* L, const char* name, ...) template<class Ret> Ret call_function(object const& obj, ...)
There are two overloads of the call_function function, one that calls a function given its name, and one that takes an object that should be a Lua value that can be called as a function.
The overload that takes a name can only call global Lua functions. The ... represents a variable number of parameters that are sent to the Lua function. This function call may throw luabind::error if the function call fails.
The return value isn't actually Ret (the template parameter), but a proxy object that will do the function call. This enables you to give policies to the call. You do this with the operator[]. You give the policies within the brackets, like this:
int ret = call_function<int>( L , "a_lua_function" , new complex_class() )[ adopt(_1) ];
If you want to pass a parameter as a reference, you have to wrap it with the Boost.Ref.
Like this:
int ret = call_function(L, "fun", boost::ref(val));
If you want to use a custom error handler for the function call, see set_pcall_callback under pcall errorfunc.
To start a Lua thread, you have to call lua_resume(), this means that you cannot use the previous function call_function() to start a thread. You have to use
template<class Ret> Ret resume_function(lua_State* L, const char* name, ...) template<class Ret> Ret resume_function(object const& obj, ...)
and
template<class Ret> Ret resume(lua_State* L, ...)
The first time you start the thread, you have to give it a function to execute. i.e. you have to use resume_function, when the Lua function yields, it will return the first value passed in to lua_yield(). When you want to continue the execution, you just call resume() on your lua_State, since it's already executing a function, you don't pass it one. The parameters to resume() will be returned by yield() on the Lua side.
For yielding C++-functions (without the support of passing data back and forth between the Lua side and the c++ side), you can use the yield policy.
With the overload of resume_function that takes an object, it is important that the object was constructed with the thread as its lua_State*. Like this:
lua_State* thread = lua_newthread(L); object fun = get_global(thread)["my_thread_fun"]; resume_function(fun);
To register classes you use a class called class_. Its name is supposed to resemble the C++ keyword, to make it look more intuitive. It has an overloaded member function def() that is used to register member functions, operators, constructors, enums and properties on the class. It will return its this-pointer, to let you register more members directly.
Let's start with a simple example. Consider the following C++ class:
class testclass { public: testclass(const std::string& s): m_string(s) {} void print_string() { std::cout << m_string << "\n"; } private: std::string m_string; };
To register it with a Lua environment, write as follows (assuming you are using namespace luabind):
module(L) [ class_<testclass>("testclass") .def(constructor<const std::string&>()) .def("print_string", &testclass::print_string) ];
This will register the class with the name testclass and constructor that takes a string as argument and one member function with the name print_string.
Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio > a = testclass('a string') > a:print_string() a string
It is also possible to register free functions as member functions. The requirement on the function is that it takes a pointer, const pointer, reference or const reference to the class type as the first parameter. The rest of the parameters are the ones that are visible in Lua, while the object pointer is given as the first parameter. If we have the following C++ code:
struct A { int a; }; int plus(A* o, int v) { return o->a + v; }
You can register plus() as if it was a member function of A like this:
class_<A>("A") .def("plus", &plus)
plus() can now be called as a member function on A with one parameter, int. If the object pointer parameter is const, the function will act as if it was a const member function (it can be called on const objects).
When binding more than one overloads of a member function, or just binding one overload of an overloaded member function, you have to disambiguate the member function pointer you pass to def. To do this, you can use an ordinary C-style cast, to cast it to the right overload. To do this, you have to know how to express member function types in C++, here's a short tutorial (for more info, refer to your favorite book on C++).
The syntax for member function pointer follows:
return-value (class-name::*)(arg1-type, arg2-type, ...)
Here's an example illlustrating this:
struct A { void f(int); void f(int, int); };
class_<A>() .def("f", (void(A::*)(int))&A::f)
This selects the first overload of the function f to bind. The second overload is not bound.
To register a global data member with a class is easily done. Consider the following class:
struct A { int a; };
This class is registered like this:
module(L) [ class_<A>("A") .def_readwrite("a", &A::a) ];
This gives read and write access to the member variable A::a. It is also possible to register attributes with read-only access:
module(L) [ class_<A>("A") .def_readonly("a", &A::a) ];
When binding members that are a non-primitive type, the auto generated getter function will return a reference to it. This is to allow chained .-operators. For example, when having a struct containing another struct. Like this:
struct A { int m; }; struct B { A a; };
When binding B to lua, the following expression code should work:
b = B() b.a.m = 1 assert(b.a.m == 1)
This requires the first lookup (on a) to return a reference to A, and not a copy. In that case, luabind will automatically use the dependency policy to make the return value dependent on the object in which it is stored. So, if the returned reference lives longer than all references to the object (b in this case) it will keep the object alive, to avoid being a dangling pointer.
You can also register getter and setter functions and make them look as if they were a public data member. Consider the following class:
class A { public: void set_a(int x) { a = x; } int get_a() const { return a; } private: int a; };
It can be registered as if it had a public data member a like this:
class_<A>("A") .property("a", &A::get_a, &A::set_a)
This way the get_a() and set_a() functions will be called instead of just writing to the data member. If you want to make it read only you can just omit the last parameter. Please note that the get function has to be const, otherwise it won't compile. This seems to be a common source of errors.
If your class contains enumerated constants (enums), you can register them as well to make them available in Lua. Note that they will not be type safe, all enums are integers in Lua, and all functions that takes an enum, will accept any integer. You register them like this:
module(L) [ class_<A>("A") .enum_("constants") [ value("my_enum", 4), value("my_2nd_enum", 7), value("another_enum", 6) ] ];
In Lua they are accessed like any data member, except that they are read-only and reached on the class itself rather than on an instance of the class.
Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio > print(A.my_enum) 4 > print(A.another_enum) 6
To bind operators you have to include <luabind/operator.hpp>.
The mechanism for registering operators on your class is pretty simple. You use a global name luabind::self to refer to the class itself and then you just write the operator expression inside the def() call. This class:
struct vec { vec operator+(int s); };
Is registered like this:
module(L) [ class_<vec>("vec") .def(self + int()) ];
This will work regardless if your plus operator is defined inside your class or as a free function.
If your operator is const (or, when defined as a free function, takes a const reference to the class itself) you have to use const_self instead of self. Like this:
module(L) [ class_<vec>("vec") .def(const_self + int()) ];
The operators supported are those available in Lua:
+ - * / == < <=
This means, no in-place operators. The equality operator (==) has a little hitch; it will not be called if the references are equal. This means that the == operator has to do pretty much what's it's expected to do.
Lua does not support operators such as !=, > or >=. That's why you can only register the operators listed above. When you invoke one of the mentioned operators, lua will define it in terms of one of the available operators.
In the above example the other operand type is instantiated by writing int(). If the operand type is a complex type that cannot easily be instantiated you can wrap the type in a class called other<>. For example:
To register this class, we don't want to instantiate a string just to register the operator.
struct vec { vec operator+(std::string); };
Instead we use the other<> wrapper like this:
module(L) [ class_<vec>("vec") .def(self + other<std::string>()) ];
To register an application (function call-) operator:
module(L) [ class_<vec>("vec") .def( self(int()) ) ];
There's one special operator. In Lua it's called __tostring, it's not really an operator. It is used for converting objects to strings in a standard way in Lua. If you register this functionality, you will be able to use the lua standard function tostring() for converting your object to a string.
To implement this operator in C++ you should supply an operator<< for std::ostream. Like this example:
class number {}; std::ostream& operator<<(std::ostream&, number&); ... module(L) [ class_<number>("number") .def(tostring(self)) ];
It is possible to add nested scopes to a class. This is useful when you need to wrap a nested class, or a static function.
class_<foo>("foo") .def(constructor<>()) .scope [ class_<inner>("nested"), def("f", &f) ];
In this example, f will behave like a static member function of the class foo, and the class nested will behave like a nested class of foo.
It's also possible to add namespaces to classes using the same syntax.
If you want to register classes that derives from other classes, you can specify a template parameter bases<> to the class_ instantiation. The following hierarchy:
struct A {}; struct B : A {};
Would be registered like this:
module(L) [ class_<A>("A"), class_<B, A>("B") ];
If you have multiple inheritance you can specify more than one base. If B would also derive from a class C, it would be registered like this:
module(L) [ class_<B, bases<A, C> >("B") ];
Note that you can omit bases<> when using single inheritance.
Note
If you don't specify that classes derive from each other, luabind will not be able to implicitly cast pointers between the types.
When registering a class you can tell luabind to hold all instances explicitly created in Lua in a specific smart pointer type, rather than the default raw pointer. This is done by passing an additional template parameter to class_:
class_<X, P>(…)
Where the requirements of P are:
| Expression | Returns |
|---|---|
| P(raw) | |
| get_pointer(p) | Convertible to X* |
where:
get_pointer() overloads are provided for the smart pointers in Boost, and std::auto_ptr<>. Should you need to provide your own overload, note that it is called unqualified and is expected to be found by argument dependent lookup. Thus it should be defined in the same namespace as the pointer type it operates on.
For example:
class_<X, boost::scoped_ptr<X> >("X") .def(constructor<>())
Will cause luabind to hold any instance created on the Lua side in a boost::scoped_ptr<X>. Note that this doesn't mean all instances will be held by a boost::scoped_ptr<X>. If, for example, you register a function:
std::auto_ptr<X> make_X();
the instance returned by that will be held in std::auto_ptr<X>. This is handled automatically for all smart pointers that implement a get_pointer() overload.
Important
get_const_holder() has been removed. Automatic conversions between smart_ptr<X> and smart_ptr<X const> no longer work.
Important
__ok has been removed. Similar functionality can be implemented for specific pointer types by doing something along the lines of:
bool is_non_null(std::auto_ptr<X> const& p) { return p.get(); } … def("is_non_null", &is_non_null)
When registering a hierarchy of classes, where all instances are to be held by a smart pointer, all the classes should have the baseclass' holder type. Like this:
module(L) [ class_<base, boost::shared_ptr<base> >("base") .def(constructor<>()), class_<derived, base, boost::shared_ptr<base> >("base") .def(constructor<>()) ];
Internally, luabind will do the necessary conversions on the raw pointers, which are first extracted from the holder type.
In some situations it may be desirable to split a registration of a class across different compilation units. Partly to save rebuild time when changing in one part of the binding, and in some cases compiler limits may force you to split it. To do this is very simple. Consider the following sample code:
void register_part1(class_<X>& x) { x.def(/*...*/); } void register_part2(class_<X>& x) { x.def(/*...*/); } void register_(lua_State* L) { class_<X> x("x"); register_part1(x); register_part2(x); module(L) [ x ]; }
Here, the class X is registered in two steps. The two functions register_part1 and register_part2 may be put in separate compilation units.
To separate the module registration and the classes to be registered, see Splitting up the registration.
It is possible to get luabind to handle user defined types like it does the built in types by specializing luabind::default_converter<>:
struct int_wrapper { int_wrapper(int value) : value(value) {} int value; }; namespace luabind { template <> struct default_converter<X> : native_converter_base<X> { static int compute_score(lua_State* L, int index) { return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; } X from(lua_State* L, int index) { return X(lua_tonumber(L, index)); } void to(lua_State* L, X const& x) { lua_pushnumber(L, x.value); } }; template <> struct default_converter<X const&> : default_converter<X> {}; }
Note that default_converter<> is instantiated for the actual argument and return types of the bound functions. In the above example, we add a specialization for X const& that simply forwards to the X converter. This lets us export functions which accept X by const reference.
native_converter_base<> should be used as the base class for the specialized converters. It simplifies the converter interface, and provides a mean for backward compatibility since the underlying interface is in flux.
Using luabind::tag_function<> it is possible to export function objects from which luabind can't automatically deduce a signature. This can be used to slightly alter the signature of a bound function, or even to bind stateful function objects.
Synopsis:
template <class Signature, class F> implementation-defined tag_function(F f);
Where Signature is a function type describing the signature of F. It can be used like this:
int f(int x); // alter the signature so that the return value is ignored def("f", tag_function<void(int)>(f)); struct plus { plus(int x) : x(x) {} int operator()(int y) const { return x + y; } }; // bind a stateful function object def("plus3", tag_function<int(int)>(plus(3)));
Since functions have to be able to take Lua values (of variable type) we need a wrapper around them. This wrapper is called luabind::object. If the function you register takes an object, it will match any Lua value. To use it, you need to include <luabind/object.hpp>.
Synopsis
class object { public: template<class T> object(lua_State*, T const& value); object(from_stack const&); object(object const&); object(); ~object(); lua_State* interpreter() const; void push() const; bool is_valid() const; operator safe_bool_type () const; template<class Key> implementation-defined operator[](Key const&); template<class T> object& operator=(T const&); object& operator=(object const&); bool operator==(object const&) const; bool operator<(object const&) const; bool operator<=(object const&) const; bool operator>(object const&) const; bool operator>=(object const&) const; bool operator!=(object const&) const; template <class T> implementation-defined operator[](T const& key) const void swap(object&); implementation-defined operator()(); template<class A0> implementation-defined operator()(A0 const& a0); template<class A0, class A1> implementation-defined operator()(A0 const& a0, A1 const& a1); /* ... */ };
When you have a Lua object, you can assign it a new value with the assignment operator (=). When you do this, the default_policy will be used to make the conversion from C++ value to Lua. If your luabind::object is a table you can access its members through the operator[] or the Iterators. The value returned from the operator[] is a proxy object that can be used both for reading and writing values into the table (using operator=).
Note that it is impossible to know if a Lua value is indexable or not (lua_gettable doesn't fail, it succeeds or crashes). This means that if you're trying to index something that cannot be indexed, you're on your own. Lua will call its panic() function. See lua panic.
There are also free functions that can be used for indexing the table, see Related functions.
The constructor that takes a from_stack object is used when you want to initialize the object with a value from the lua stack. The from_stack type has the following constructor:
from_stack(lua_State* L, int index);
The index is an ordinary lua stack index, negative values are indexed from the top of the stack. You use it like this:
object o(from_stack(L, -1));
This will create the object o and copy the value from the top of the lua stack.
The interpreter() function returns the Lua state where this object is stored. If you want to manipulate the object with Lua functions directly you can push it onto the Lua stack by calling push().
The operator== will call lua_equal() on the operands and return its result.
The is_valid() function tells you whether the object has been initialized or not. When created with its default constructor, objects are invalid. To make an object valid, you can assign it a value. If you want to invalidate an object you can simply assign it an invalid object.
The operator safe_bool_type() is equivalent to is_valid(). This means that these snippets are equivalent:
object o; // ... if (o) { // ... } ... object o; // ... if (o.is_valid()) { // ... }
The application operator will call the value as if it was a function. You can give it any number of parameters (currently the default_policy will be used for the conversion). The returned object refers to the return value (currently only one return value is supported). This operator may throw luabind::error if the function call fails. If you want to specify policies to your function call, you can use index-operator (operator[]) on the function call, and give the policies within the [ and ]. Like this:
my_function_object( 2 , 8 , new my_complex_structure(6) ) [ adopt(_3) ];
This tells luabind to make Lua adopt the ownership and responsibility for the pointer passed in to the lua-function.
It's important that all instances of object have been destructed by the time the Lua state is closed. The object will keep a pointer to the lua state and release its Lua object in its destructor.
Here's an example of how a function can use a table:
void my_function(object const& table) { if (type(table) == LUA_TTABLE) { table["time"] = std::clock(); table["name"] = std::rand() < 500 ? "unusual" : "usual"; std::cout << object_cast<std::string>(table[5]) << "\n"; } }
If you take a luabind::object as a parameter to a function, any Lua value will match that parameter. That's why we have to make sure it's a table before we index into it.
std::ostream& operator<<(std::ostream&, object const&);
There's a stream operator that makes it possible to print objects or use boost::lexical_cast to convert it to a string. This will use lua's string conversion function. So if you convert a C++ object with a tostring operator, the stream operator for that type will be used.
There are two kinds of iterators. The normal iterator that will use the metamethod of the object (if there is any) when the value is retrieved. This iterator is simply called luabind::iterator. The other iterator is called luabind::raw_iterator and will bypass the metamethod and give the true contents of the table. They have identical interfaces, which implements the ForwardIterator concept. Apart from the members of standard iterators, they have the following members and constructors:
class iterator { iterator(); iterator(object const&); object key() const; standard iterator members };
The constructor that takes a luabind::object is actually a template that can be used with object. Passing an object as the parameter to the iterator will construct the iterator to refer to the first element in the object.
The default constructor will initialize the iterator to the one-past-end iterator. This is used to test for the end of the sequence.
The value type of the iterator is an implementation defined proxy type which supports the same operations as luabind::object. Which means that in most cases you can just treat it as an ordinary object. The difference is that any assignments to this proxy will result in the value being inserted at the iterators position, in the table.
The key() member returns the key used by the iterator when indexing the associated Lua table.
An example using iterators:
for (iterator i(globals(L)["a"]), end; i != end; ++i) { *i = 1; }
The iterator named end will be constructed using the default constructor and hence refer to the end of the sequence. This example will simply iterate over the entries in the global table a and set all its values to 1.
To set a table entry to nil, you can use luabind::nil. It will avoid having to take the detour by first assigning nil to an object and then assign that to the table entry. It will simply result in a lua_pushnil() call, instead of copying an object.
Example:
using luabind; object table = newtable(L); table["foo"] = "bar"; // now, clear the "foo"-field table["foo"] = nil;
In addition to binding C++ functions and classes with Lua, luabind also provide an OO-system in Lua.
class 'lua_testclass' function lua_testclass:__init(name) self.name = name end function lua_testclass:print() print(self.name) end a = lua_testclass('example') a:print()
Inheritance can be used between lua-classes:
class 'derived' (lua_testclass) function derived:__init() lua_testclass.__init(self, 'derived name') end function derived:print() print('Derived:print() -> ') lua_testclass.print(self) end
The base class is initialized explicitly by calling its __init() function.
As you can see in this example, you can call the base class member functions. You can find all member functions in the base class, but you will have to give the this-pointer (self) as first argument.
It is also possible to derive Lua classes from C++ classes, and override virtual functions with Lua functions. To do this we have to create a wrapper class for our C++ base class. This is the class that will hold the Lua object when we instantiate a Lua class.
class base { public: base(const char* s) { std::cout << s << "\n"; } virtual void f(int a) { std::cout << "f(" << a << ")\n"; } }; struct base_wrapper : base, luabind::wrap_base { base_wrapper(const char* s) : base(s) {} virtual void f(int a) { call<void>("f", a); } static void default_f(base* ptr, int a) { return ptr->base::f(a); } }; ... module(L) [ class_<base, base_wrapper>("base") .def(constructor<const char*>()) .def("f", &base::f, &base_wrapper::default_f) ];
Important
Since MSVC6.5 doesn't support explicit template parameters to member functions, instead of using the member function call() you call a free function call_member() and pass the this-pointer as first parameter.
Note that if you have both base classes and a base class wrapper, you must give both bases and the base class wrapper type as template parameter to class_ (as done in the example above). The order in which you specify them is not important. You must also register both the static version and the virtual version of the function from the wrapper, this is necessary in order to allow luabind to use both dynamic and static dispatch when calling the function.
Important
It is extremely important that the signatures of the static (default) function is identical to the virtual function. The fact that one of them is a free function and the other a member function doesn't matter, but the parameters as seen from lua must match. It would not have worked if the static function took a base_wrapper* as its first argument, since the virtual function takes a base* as its first argument (its this pointer). There's currently no check in luabind to make sure the signatures match.
If we didn't have a class wrapper, it would not be possible to pass a Lua class back to C++. Since the entry points of the virtual functions would still point to the C++ base class, and not to the functions defined in Lua. That's why we need one function that calls the base class' real function (used if the lua class doesn't redefine it) and one virtual function that dispatches the call into luabind, to allow it to select if a Lua function should be called, or if the original function should be called. If you don't intend to derive from a C++ class, or if it doesn't have any virtual member functions, you can register it without a class wrapper.
You don't need to have a class wrapper in order to derive from a class, but if it has virtual functions you may have silent errors.
The wrappers must derive from luabind::wrap_base, it contains a Lua reference that will hold the Lua instance of the object to make it possible to dispatch virtual function calls into Lua. This is done through an overloaded member function:
template<class Ret> Ret call(char const* name, ...)
Its used in a similar way as call_function, with the exception that it doesn't take a lua_State pointer, and the name is a member function in the Lua class.
Warning
The current implementation of call_member is not able to distinguish const member functions from non-const. If you have a situation where you have an overloaded virtual function where the only difference in their signatures is their constness, the wrong overload will be called by call_member. This is rarely the case though.
When a pointer or reference to a registered class with a wrapper is passed to Lua, luabind will query for it's dynamic type. If the dynamic type inherits from wrap_base, object identity is preserved.
struct A { .. }; struct A_wrap : A, wrap_base { .. }; A* f(A* ptr) { return ptr; } module(L) [ class_<A, A_wrap>("A"), def("f", &f) ];
> class 'B' (A) > x = B() > assert(x == f(x)) -- object identity is preserved when object is -- passed through C++
This functionality relies on RTTI being enabled (that LUABIND_NO_RTTI is not defined).
You can overload most operators in Lua for your classes. You do this by simply declaring a member function with the same name as an operator (the name of the metamethods in Lua). The operators you can overload are:
- __add
- __sub
- __mul
- __div
- __pow
- __lt
- __le
- __eq
- __call
- __unm
- __tostring
- __len
__tostring isn't really an operator, but it's the metamethod that is called by the standard library's tostring() function. There's one strange behavior regarding binary operators. You are not guaranteed that the self pointer you get actually refers to an instance of your class. This is because Lua doesn't distinguish the two cases where you get the other operand as left hand value or right hand value. Consider the following examples:
class 'my_class' function my_class:__init(v) self.val = v end function my_class:__sub(v) return my_class(self.val - v.val) end function my_class:__tostring() return self.val end
This will work well as long as you only subtracts instances of my_class with each other. But If you want to be able to subtract ordinary numbers from your class too, you have to manually check the type of both operands, including the self object.
function my_class:__sub(v) if (type(self) == 'number') then return my_class(self - v.val) elseif (type(v) == 'number') then return my_class(self.val - v) else -- assume both operands are instances of my_class return my_class(self.val - v.val) end end
The reason why __sub is used as an example is because subtraction is not commutative (the order of the operands matters). That's why luabind cannot change order of the operands to make the self reference always refer to the actual class instance.
If you have two different Lua classes with an overloaded operator, the operator of the right hand side type will be called. If the other operand is a C++ class with the same operator overloaded, it will be prioritized over the Lua class' operator. If none of the C++ overloads matches, the Lua class operator will be called.
If an object needs to perform actions when it's collected we provide a __finalize function that can be overridden in lua-classes. The __finalize functions will be called on all classes in the inheritance chain, starting with the most derived type.
... function lua_testclass:__finalize() -- called when the an object is collected end
If your lua C++ classes don't have wrappers (see Deriving in lua) and you derive from them in lua, they may be sliced. Meaning, if an object is passed into C++ as a pointer to its base class, the lua part will be separated from the C++ base part. This means that if you call virtual functions on that C++ object, they will not be dispatched to the lua class. It also means that if you adopt the object, the lua part will be garbage collected.
+--------------------+ | C++ object | <- ownership of this part is transferred | | to c++ when adopted +--------------------+ | lua class instance | <- this part is garbage collected when | and lua members | instance is adopted, since it cannot +--------------------+ be held by c++.
The problem can be illustrated by this example:
struct A {}; A* filter_a(A* a) { return a; } void adopt_a(A* a) { delete a; }
using namespace luabind; module(L) [ class_<A>("A"), def("filter_a", &filter_a), def("adopt_a", &adopt_a, adopt(_1)) ]
In lua:
a = A() b = filter_a(a) adopt_a(b)
In this example, lua cannot know that b actually is the same object as a, and it will therefore consider the object to be owned by the C++ side. When the b pointer then is adopted, a runtime error will be raised because an object not owned by lua is being adopted to C++.
If you have a wrapper for your class, none of this will happen, see Object identity.
If any of the functions you register throws an exception when called, that exception will be caught by luabind and converted to an error string and lua_error() will be invoked. If the exception is a std::exception or a const char* the string that is pushed on the Lua stack, as error message, will be the string returned by std::exception::what() or the string itself respectively. If the exception is unknown, a generic string saying that the function threw an exception will be pushed.
If you have an exception type that isn't derived from std::exception, or you wish to change the error message from the default result of what(), it is possible to register custom exception handlers:
struct my_exception {}; void translate_my_exception(lua_State* L, my_exception const&) { lua_pushstring(L, "my_exception"); } … luabind::register_exception_handler<my_exception>(&translate_my_exception);
translate_my_exception() will be called by luabind whenever a my_exception is caught. lua_error() will be called after the handler function returns, so it is expected that the function will push an error string on the stack.
Any function that invokes Lua code may throw luabind::error. This exception means that a Lua run-time error occurred. The error message is found on top of the Lua stack. The reason why the exception doesn't contain the error string itself is because it would then require heap allocation which may fail. If an exception class throws an exception while it is being thrown itself, the application will be terminated.
Error's synopsis is:
class error : public std::exception { public: error(lua_State*); lua_State* state() const throw(); virtual const char* what() const throw(); };
The state function returns a pointer to the Lua state in which the error was thrown. This pointer may be invalid if you catch this exception after the lua state is destructed. If the Lua state is valid you can use it to retrieve the error message from the top of the Lua stack.
An example of where the Lua state pointer may point to an invalid state follows:
struct lua_state { lua_state(lua_State* L): m_L(L) {} ~lua_state() { lua_close(m_L); } operator lua_State*() { return m_L; } lua_State* m_L; }; int main() { try { lua_state L = lua_open(); /* ... */ } catch(luabind::error& e) { lua_State* L = e.state(); // L will now point to the destructed // Lua state and be invalid /* ... */ } }
There's another exception that luabind may throw: luabind::cast_failed, this exception is thrown from call_function<> or call_member<>. It means that the return value from the Lua function couldn't be converted to a C++ value. It is also thrown from object_cast<> if the cast cannot be made.
The synopsis for luabind::cast_failed is:
class cast_failed : public std::exception { public: cast_failed(lua_State*); lua_State* state() const throw(); LUABIND_TYPE_INFO info() const throw(); virtual const char* what() const throw(); };
Again, the state member function returns a pointer to the Lua state where the error occurred. See the example above to see where this pointer may be invalid.
The info member function returns the user defined LUABIND_TYPE_INFO, which defaults to a const std::type_info*. This type info describes the type that we tried to cast a Lua value to.
If you have defined LUABIND_NO_EXCEPTIONS none of these exceptions will be thrown, instead you can set two callback functions that are called instead. These two functions are only defined if LUABIND_NO_EXCEPTIONS are defined.
luabind::set_error_callback(void(*)(lua_State*))
The function you set will be called when a runtime-error occur in Lua code. You can find an error message on top of the Lua stack. This function is not expected to return, if it does luabind will call std::terminate().
luabind::set_cast_failed_callback(void(*)(lua_State*, LUABIND_TYPE_INFO))
The function you set is called instead of throwing cast_failed. This function is not expected to return, if it does luabind will call std::terminate().
Sometimes it is necessary to control how luabind passes arguments and return value, to do this we have policies. All policies use an index to associate them with an argument in the function signature. These indices are result and _N (where N >= 1). When dealing with member functions _1 refers to the this pointer.
Policies currently implemented
Used to transfer ownership across language boundaries.
#include <luabind/adopt_policy.hpp>
adopt(index)
| Parameter | Purpose |
|---|---|
| index | The index which should transfer ownership, _N or result |
X* create() { return new X; } ... module(L) [ def("create", &create, adopt(result)) ];
The dependency policy is used to create life-time dependencies between values. This is needed for example when returning internal references to some class.
#include <luabind/dependency_policy.hpp>
dependency(nurse_index, patient_index)
| Parameter | Purpose |
|---|---|
| nurse_index | The index which will keep the patient alive. |
| patient_index | The index which will be kept alive. |
struct X { B member; B& get() { return member; } }; module(L) [ class_<X>("X") .def("get", &X::get, dependency(result, _1)) ];
This policy makes it possible to wrap functions that take non-const references or pointer to non-const as it's parameters with the intention to write return values to them. Since it's impossible to pass references to primitive types in lua, this policy will add another return value with the value after the call. If the function already has one return value, one instance of this policy will add another return value (read about multiple return values in the lua manual).
#include <luabind/out_value_policy.hpp>
out_value(index, policies = none)
| Parameter | Purpose |
|---|---|
| index | The index of the parameter to be used as an out parameter. |
| policies | The policies used internally to convert the out parameter to/from Lua. _1 means to C++, _2 means from C++. |
void f1(float& val) { val = val + 10.f; } void f2(float* val) { *val = *val + 10.f; } module(L) [ def("f", &f, out_value(_1)) ]; Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio > print(f1(10)) 20 > print(f2(10)) 20
This works exactly like out_value, except that it will pass a default constructed object instead of converting an argument from Lua. This means that the parameter will be removed from the lua signature.
#include <luabind/out_value_policy.hpp>
pure_out_value(index, policies = none)
| Parameter | Purpose |
|---|---|
| index | The index of the parameter to be used as an out parameter. |
| policies | The policies used internally to convert the out parameter to Lua. _1 is used as the internal index. |
Note that no values are passed to the calls to f1 and f2.
void f1(float& val) { val = 10.f; } void f2(float* val) { *val = 10.f; } module(L) [ def("f", &f, pure_out_value(_1)) ]; Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio > print(f1()) 10 > print(f2()) 10
It is very common to return references to arguments or the this-pointer to allow for chaining in C++.
struct A { float val; A& set(float v) { val = v; return *this; } };
When luabind generates code for this, it will create a new object for the return-value, pointing to the self-object. This isn't a problem, but could be a bit inefficient. When using the return_reference_to-policy we have the ability to tell luabind that the return-value is already on the lua stack.
#include <luabind/return_reference_to_policy.hpp>
return_reference_to(index)
| Parameter | Purpose |
|---|---|
| index | The argument index to return a reference to, any argument but not result. |
struct A { float val; A& set(float v) { val = v; return *this; } }; module(L) [ class_<A>("A") .def(constructor<>()) .def("set", &A::set, return_reference_to(_1)) ];
Warning
This policy ignores all type information and should be used only it situations where the parameter type is a perfect match to the return-type (such as in the example).
This will make a copy of the parameter. This is the default behavior when passing parameters by-value. Note that this can only be used when passing from C++ to Lua. This policy requires that the parameter type has an accessible copy constructor.
#include <luabind/copy_policy.hpp>
copy(index)
| Parameter | Purpose |
|---|---|
| index | The index to copy. result when used while wrapping C++ functions. _N when passing arguments to Lua. |
X* get() { static X instance; return &instance; } ... module(L) [ def("create", &create, copy(result)) ];
This is a very simple policy which makes it possible to throw away the value returned by a C++ function, instead of converting it to Lua.
#include <luabind/discard_result_policy.hpp>
discard_result
struct X { X& set(T n) { ... return *this; } }; ... module(L) [ class_<X>("X") .def("set", &simple::set, discard_result) ];
This policy converts an STL container to a generator function that can be used in lua to iterate over the container. It works on any container that defines begin() and end() member functions (they have to return iterators).
#include <luabind/iterator_policy.hpp>
return_stl_iterator
struct X { std::vector<std::string> names; }; ... module(L) [ class_<A>("A") .def_readwrite("names", &X::names, return_stl_iterator) ]; ... > a = A() > for name in a.names do > print(name) > end
Note
raw() has been deprecated. lua_State* parameters are automatically handled by luabind.
This converter policy will pass through the lua_State* unmodified. This can be useful for example when binding functions that need to return a luabind::object. The parameter will be removed from the function signature, decreasing the function arity by one.
#include <luabind/raw_policy.hpp>
raw(index)
| Parameter | Purpose |
|---|---|
| index | The index of the lua_State* parameter. |
void greet(lua_State* L) { lua_pushstring(L, "hello"); } ... module(L) [ def("greet", &greet, raw(_1)) ]; > print(greet()) hello
Makes a C++ function yield when returning.
#include <luabind/yield_policy.hpp>
yield
void do_thing_that_takes_time() { ... } ... module(L) [ def("do_thing_that_takes_time", &do_thing_that_takes_time, yield) ];
It is possible to split up a module registration into several translation units without making each registration dependent on the module it's being registered in.
a.cpp:
luabind::scope register_a() { return class_<a>("a") .def("f", &a::f) ; }
b.cpp:
luabind::scope register_b() { return class_<b>("b") .def("g", &b::g) ; }
module_ab.cpp:
luabind::scope register_a(); luabind::scope register_b(); void register_module(lua_State* L) { module("b", L) [ register_a(), register_b() ]; }
As mentioned in the Lua documentation, it is possible to pass an error handler function to lua_pcall(). Luabind makes use of lua_pcall() internally when calling member functions and free functions. It is possible to set the error handler function that Luabind will use globally:
typedef int(*pcall_callback_fun)(lua_State*); void set_pcall_callback(pcall_callback_fun fn);
This is primarily useful for adding more information to the error message returned by a failed protected call. For more information on how to use the pcall_callback function, see errfunc under the pcall section of the lua manual.
For more information on how to retrieve debugging information from lua, see the debug section of the lua manual.
The message returned by the pcall_callback is accessable as the top lua value on the stack. For example, if you would like to access it as a luabind object, you could do like this:
catch(error& e) { object error_msg(from_stack(e.state(), -1)); std::cout << error_msg << std::endl; }
If you want to add file name and line number to the error messages generated by luabind you can define your own pcall errorfunc. You may want to modify this callback to better suit your needs, but the basic functionality could be implemented like this:
int add_file_and_line(lua_State* L) { lua_Debug d; lua_getstack(L, 1, &d); lua_getinfo(L, "Sln", &d); std::string err = lua_tostring(L, -1); lua_pop(L, 1); std::stringstream msg; msg << d.short_src << ":" << d.currentline; if (d.name != 0) { msg << "(" << d.namewhat << " " << d.name << ")"; } msg << " " << err; lua_pushstring(L, msg.str().c_str()); return 1; }
For more information about what kind of information you can add to the error message, see the debug section of the lua manual.
Note that the callback set by set_pcall_callback() will only be used when luabind executes lua code. Anytime when you call lua_pcall yourself, you have to supply your function if you want error messages translated.
When lua encounters a fatal error caused by a bug from the C/C++ side, it will call its internal panic function. This can happen, for example, when you call lua_gettable on a value that isn't a table. If you do the same thing from within lua, it will of course just fail with an error message.
The default panic function will exit() the application. If you want to handle this case without terminating your application, you can define your own panic function using lua_atpanic. The best way to continue from the panic function is to make sure lua is compiled as C++ and throw an exception from the panic function. Throwing an exception instead of using setjmp and longjmp will make sure the stack is correctly unwound.
When the panic function is called, the lua state is invalid, and the only allowed operation on it is to close it.
For more information, see the lua manual section 3.19.
Since lua is generally built as a C library, any callbacks called from lua cannot under any circumstance throw an exception. Because of that, luabind has to catch all exceptions and translate them into proper lua errors (by calling lua_error()). This means we have a catch(...) {} in there.
In Visual Studio, catch (...) will not only catch C++ exceptions, it will also catch structured exceptions, such as segmentation fault. This means that if your function, that gets called from luabind, makes an invalid memory adressing, you won't notice it. All that will happen is that lua will return an error message saying "unknown exception".
To remedy this, you can create your own exception translator:
void straight_to_debugger(unsigned int, _EXCEPTION_POINTERS*) { throw; } #ifdef _MSC_VER ::_set_se_translator(straight_to_debugger); #endif
This will make structured exceptions, like segmentation fault, to actually get caught by the debugger.
These are the error messages that can be generated by luabind, with a more in-depth explanation.
the attribute 'class-name.attribute-name' is read only
There is no data member named attribute-name in the class class-name, or there's no setter-function registered on that property name. See the Properties section.
the attribute 'class-name.attribute-name' is of type: (class-name) and does not match (class_name)
This error is generated if you try to assign an attribute with a value of a type that cannot be converted to the attributes type.
class-name() threw an exception, class-name:function-name() threw an exception
The class' constructor or member function threw an unknown exception. Known exceptions are const char*, std::exception. See the exceptions section.
no overload of 'class-name:function-name' matched the arguments (parameter-types) no match for function call 'function-name' with the parameters (parameter-types) no constructor of class-name matched the arguments (parameter-types) no operator operator-name matched the arguments (parameter-types)
No function/operator with the given name takes the parameters you gave it. You have either misspelled the function name, or given it incorrect parameters. This error is followed by a list of possible candidate functions to help you figure out what parameter has the wrong type. If the candidate list is empty there's no function at all with that name. See the signature matching section.
call of overloaded 'class-name:function-name*(*parameter-types)' is ambiguous ambiguous match for function call 'function-name' with the parameters (parameter-types) call of overloaded constructor 'class-name*(*parameter-types)' is ambiguous call of overloaded operator operator-name (parameter-types) is ambiguous
This means that the function/operator you are trying to call has at least one other overload that matches the arguments just as good as the first overload.
cannot derive from C++ class 'class-name'. It does not have a wrapped type.
There are a number of configuration options available when building luabind. It is very important that your project has the exact same configuration options as the ones given when the library was build! The exceptions are the LUABIND_MAX_ARITY and LUABIND_MAX_BASES which are template-based options and only matters when you use the library (which means they can differ from the settings of the library).
The default settings which will be used if no other settings are given can be found in luabind/config.hpp.
If you want to change the settings of the library, you can modify the config file. It is included and used by all makefiles. You can change paths to Lua and boost in there as well.
If this macro is defined, all the Lua code is expected only to make legal calls. If illegal function calls are made (e.g. giving parameters that doesn't match the function signature) they will not be detected by luabind and the application will probably crash. Error checking could be disabled when shipping a release build (given that no end-user has access to write custom Lua code). Note that function parameter matching will be done if a function is overloaded, since otherwise it's impossible to know which one was called. Functions will still be able to throw exceptions when error checking is disabled.
If a function throws an exception it will be caught by luabind and propagated with lua_error().
This define will disable all usage of try, catch and throw in luabind. This will in many cases disable run-time errors, when performing invalid casts or calling Lua functions that fails or returns values that cannot be converted by the given policy. luabind requires that no function called directly or indirectly by luabind throws an exception (throwing exceptions through Lua has undefined behavior).
Where exceptions are the only way to get an error report from luabind, they will be replaced with calls to the callback functions set with set_error_callback() and set_cast_failed_callback().
The classes and objects are implemented as user data in Lua. To make sure that the user data really is the internal structure it is supposed to be, we tag their metatables. A user data who's metatable contains a boolean member named __luabind_classrep is expected to be a class exported by luabind. A user data who's metatable contains a boolean member named __luabind_class is expected to be an instantiation of a luabind class.
This means that if you make your own user data and tags its metatable with the exact same names, you can very easily fool luabind and crash the application.
In the Lua registry, luabind keeps an entry called __luabind_classes. It should not be removed or overwritten.
In the global table, a variable called super is used every time a constructor in a lua-class is called. This is to make it easy for that constructor to call its base class' constructor. So, if you have a global variable named super it may be overwritten. This is probably not the best solution, and this restriction may be removed in the future.
Note
Deprecated
super() has been deprecated since version 0.8 in favor of directly invoking the base class' __init() function:
function Derived:__init() Base.__init(self) end
Luabind uses two upvalues for functions that it registers. The first is a userdata containing a list of overloads for the function, the other is a light userdata with the value 0x1337, this last value is used to identify functions registered by luabind. It should be virtually impossible to have such a pointer as secondary upvalue by pure chance. This means, if you are trying to replace an existing function with a luabind function, luabind will see that the secondary upvalue isn't the magic id number and replace it. If it can identify the function to be a luabind function, it won't replace it, but rather add another overload to it.
Inside the luabind namespace, there's another namespace called detail. This namespace contains non-public classes and are not supposed to be used directly.
If you're compiling in debug mode, you will probably have a lot of debug-info and symbols (luabind consists of a lot of functions). Also, if built in debug mode, no optimizations were applied, luabind relies on that the compiler is able to inline functions. If you built in release mode, try running strip on your executable to remove export-symbols, this will trim down the size.
Our tests suggests that cygwin's gcc produces much bigger executables compared to gcc on other platforms and other compilers.
Yes you can, but you can only register explicit instantiations of the class. Because there's no Lua counterpart to C++ templates. For example, you can register an explicit instantiation of std::vector<> like this:
module(L) [ class_<std::vector<int> >("vector") .def(constructor<int>) .def("push_back", &std::vector<int>::push_back) ];
No, the destructor of a class is always called by luabind when an object is collected. Note that Lua has to own the object to collect it. If you pass it to C++ and gives up ownership (with adopt policy) it will no longer be owned by Lua, and not collected.
If you have a class hierarchy, you should make the destructor virtual if you want to be sure that the correct destructor is called (this apply to C++ in general).
Written by Daniel Wallin and Arvid Norberg. © Copyright 2003. All rights reserved.
Evan Wies has contributed with thorough testing, countless bug reports and feature ideas.
This library was highly inspired by Dave Abrahams' Boost.Python library.


The idea for this series was sparked when I was helping some people research sample flipped lessons for a curriculum workshop I was facilitating. I was embarrassed while working with this teacher because most of what we found was significantly below standard.
That night, I did some more searching and I leafed through page after page of Google results of substitution-level implementations of flipping. Lessons that came up in the search were roughly:
What I could not find were resources on designing effective and powerful lessons for flipping, let alone units.
This is a problem.
In my early years, a unit was simply a sequence of lessons around a central theme. Essential Questions guided my day to day work, but instead of focusing on content standards as a baseline, I relied on thematic relationships. At the time, I thought I was giving myself freedom to explore related ideas no “prescribed in the curriculum.” In reality, I was making more work for myself as I pulled ideas in without a guiding framework. On top of cherry-picking pieces of content within a unit, I was trying to flip everything. That meant making videos and corresponding materials to help my students in their learning. The majority of my work was focused on lesson preparation and the overall unit structure was left to nothing more than the sum of the parts.
Flipped Learning has been around long enough for most people to have heard about it if not researched it for themselves. Sal Khan’s 2011 TED talk is a firestarter for conversation among teachers and administrators looking for methods to jumpstart some innovation. Jon Bergmann and Aaron Sams have published a number of books about flipping at the classroom level as well as for particular subjects. Others like Crystal Kirch, Troy Cockrum, Robert Talbert, and Ramsey Musallam have written books (all linked) about their implementation strategies teachers can model as they begin to explore.
There is a significant information gap when it comes to learning about how to successfully implement flipped practices. In a culture of Google results and “power skimming,” most implementations begin - and end - with finding or recording lectures that students watch at home and then “apply” in the classroom.
At it’s worst, the teacher becomes a non-essential mediator of student YouTube binging. At best, the teacher essentially resets the clock on student work, promoting passive listening and devaluing the net positives that can be gained in a classroom setting.
Sherry Turkle explores the advent of using technology to engage today’s “disengaged” students in her book, Reclaiming Conversation. Her point is similar - rich classrooms come with discussion and interaction. Savvy and intentional course design is key in promoting this interaction. Flipped Learning can help you build that culture, but only if you’re prepared with the right instructional tools.
So, our question: When you’re asked to design a lesson, where do you start?
Like many, you may identify your Big Idea and Essential Question for the day (don’t forget to put them on the board!). Then, you’d outline your instruction and some guided practice strategies after which you can assess student understanding of the material.
Lessons are easy. As a teacher, you’ve been crafting lessons since your undergrad years. Over time, they may be refined or updated, but planning is typically spent looking at a calendar, outlining day to day activities.
When you design from the top - starting with the biggest ideas and burrowing down through assessment and lessons - you are rooted in the main ideas. Those themes permeate everything your students do, which leads to more opportunities for exploration and discussions on related topics. You won’t need to think about every contingency to engage students when they lose interest because students will define those topics themselves.
Our worldview informs everything we do in the classroom. “The medium is the message,” the adage goes, and it’s particularly important to remember as you begin to incorporate video (or other media) into your instructional habits. The idea of an asynchronous introductory event is not a common experience for most of our students. How will it communicate a shift in the typical learning cycle?
Our bubbles are strong. Our brains work hard to fit new experiences into existing schemas. When they don’t fit, the schema is broken down and rebuilt. Working in a flipped environment will certainly break your students schemas about learning. If your schema for instruction isn’t being broken and rebuilt as part of the process, your wheels will spin.
To address the shortcomings of planning effectively for flipped material, we’ll be using a modified version Simon Sinek’s “Golden Circle” to plan out a holistic unit from the top down. If you’re not familiar with the Golden Circle, here’s a diagram:
The Golden Circle is meant to help organizations determine their core mission. In many cases, employees (or teachers and students) can quickly answer What it is they do every day. For example, a Microsoft employee would say they make software. A student would say they’re learning about the Revolutionary War or linear equations.
Most people, however, can’t answer the “Why” nearly as easily. Why does Microsoft make software? Why are linear equations taught in school? Sinek’s argument for the corporate world is that by answering the Why for your clients, you stand out - you become unique and a cohesive and productive culture develops.
Schools are not businesses, but the principles of the Golden Circle can be applied to curriculum development. How do we transfer corporate descriptors to the classroom?
In our application, we’re going to put the Why at the outside, exchanging it for the What:
This Golden Circle hangs on a wall near my desk. It’s a visual reminder as I work with teachers to build units of instruction. Everything defined in the unit is nested and related: all of the What is measured and related to the defined Why. The idea is to root our planning in practices which focus on teaching standards with authentic and meaningful opportunities for assessment.
Admittedly, the visual analogy isn’t perfect because usually, when a dartboard is involved, you’re shooting for the bullseye. We need to get to the what eventually, but it’s always within the context of what’s around it, the standards and assessments.
Each post in this series will dive deeper into designing units of instruction rather than flipped lessons. Comments, suggestions, and feedback are always appreciated.
Written on January 6th, 2018 by Brian Bennett Categorized in: FLN Hub Flipclass
Leave a comment


Available in large (1024x683) and medium (500x333) formats in colour and monochrome.
DownloadA self-professed map addict, Gary has worked in the mapping and location space for over 20 years through a combination of luck and occasional good judgement. He is co-founder and director of Malstow Geospatial, a consultancy firm offering bespoke consulting and services in the geospatial, geotechnology, maps and location based services fields. This means Gary is currently consulting as Head of APIs for the Ordnance Survey, the United Kingdom's national mapping agency. A Fellow of the RGS, he tweets about maps, writes about them and even makes them.
A self-professed geek and map addict, Gary has worked in the mapping and location space for over 20 years through a combination of luck and occasional good judgement. He is co-founder and director of Malstow Geospatial, a consultancy firm offering bespoke consulting and services in the geospatial, geotechnology, maps and location based services fields. This means Gary is currently consulting as Head of APIs for the Ordnance Survey, the United Kingdom's national mapping agency.
Although based in London, where he lives with his family, Gary works from anywhere with the magic combination of good coffee, free Wi-Fi and somewhere to charge his laptop.
Previously Gary was Director of Places and Director of Global Community Programs for Nokia’s HERE Maps. Prior to this led Yahoo’s UK Geo Technologies group, releasing the GeoPlanet and PlaceMaker APIS as well as helping Flickr and Fire Eagle do location based services and even worked at the European Space Agency, a job which really was rocket science.
Despite working on mapping strategies and global projects, Gary continues to keep coding, mainly on planes, as maintainer for the Mapstraction JavaScript mapping API and has been known to make the odd WordPress plugin or two. He also talks at conferences a lot.
Gary has been tweeting about maps as @vicchi since 2007, writing about maps at www.vicchi.org since 2001 and also makes the occasional map at maps.geotastic.org.
A fellow of the Royal Geographical Society, Gary sits on the Executive for the AGI, the United Kingdom’s Association for Geographic Information, is a founder of the Location Forum, the co-founder of WhereCamp EU and conference chair of W3G.
The full version, for when you have more space or when you want to get the bigger picture.
Download (Word) Download (PDF)