Re: Prototype-Based Programming
- Posted by mattlewis (admin) Sep 26, 2013
- 2249 views
I whipped up a really simple framework for doing prototype based programming in euphoria. This probably duplicates some of the old OOP libraries in the archive, except that it uses euphoria's maps and it has no error checking.
-- prototype.e namespace proto include std/map.e public type prototype( object p ) return map( p ) end type public function new( object p = "" ) if prototype( p ) then return map:copy( p ) else return map:new() end if end function public function call( prototype p, object method, object args = {}) if atom( args ) then args = { p, args } else args = prepend( args, p ) end if return call_func( map:get( p, method ), args ) end function public function get( prototype p, object property ) return map:get( p, property ) end function public procedure set( prototype p, object property, object value ) map:put( p, property, value ) end procedure
...and then it could be used like so:
-- prototype.ex include prototype.e enum NAME, LIFEPOINTS, GREET prototype creature = proto:new() proto:set( creature, NAME, "" ) proto:set( creature, LIFEPOINTS, 100 ) function person_greeter( prototype p ) printf(1, "Hello, my name is %s\n", { proto:get( p, NAME ) }) return 0 end function prototype person = proto:new( creature ) proto:set( person, GREET, routine_id("person_greeter") ) prototype bob = proto:new( person ) proto:set( bob, NAME, "Bob" ) function hispanic_greeting( prototype p ) printf(1, "Hola, me llamo %s\n", { proto:get( p, NAME ) }) return 0 end function prototype juan = proto:new( person ) proto:set( juan, GREET, routine_id("hispanic_greeting" ) ) proto:set( juan, NAME, "Juan" ) prototype luis = proto:new( juan ) proto:set( luis, NAME, "Luis" ) proto:call( bob, GREET ) proto:call( juan, GREET ) proto:call( luis, GREET )
$ eui prototype.ex Hello, my name is Bob Hola, me llamo Juan Hola, me llamo Luis
Obviously, any method needs to have the prototype object be its first parameter. Method / property identifiers can be whatever you want. I used an enum, but you could have sequences or whatever there. If you try to "get" something meant as a method, you'll get the routine id, of course. If you try to call a property, you'll likely get an error, unless the value is a valid routine id and your arguments match the signature of the target.
Matt