[erlang-questions] If you are homesick for object.selector

David Goehrig <>
Fri Jan 25 13:33:39 CET 2013


On Thu, Jan 24, 2013 at 10:18 AM, Loïc Hoguin <> wrote:

>
> Assume a variable Character. This variable contains everything about the
> character. How do you best access and modify Character? The answer must not
> involve the process dictionary, processes or message passing. Today I have
> to write each access and modification function. Or I can generate it, but
> either way I end up with hundreds of functions in many modules.


Assuming that "you're doing it wrong" and you make "doing this wrong" a
requirement, the easiest way is nested proplists (as would effectively be
the case in Perl, Python, Ruby, Javascript, Lua, etc. minus some fine
points of the implementations of the dictionaries, hashes, and tables), and
two utility functions:

  of(Object,Property) -> proplists:get_value(Property,Object).

  has(Object,Property,Value) -> [ { Property, Value } |
proplists:delete(Property,Object) ].

Where due to the horrible nature of the beast Character.weapon.ability.cost
is:

    of(of(of(Character,weapon),ability),cost).

And the assignment Character.weapon.ability.cost := 123 is:

  Character2 = has(Character,weapon, has(of(Character,weapon), ability),
has(of(of(Character,weapon),ability), cost, 123))).

Which of course once again only goes to suggest "you're doing it wrong",
but at least you aren't writing reams of code for each object type.  This
would then lend itself to abstracting out each "type" of setting if you
want to feel like you're doing something "object oriented":

    character:wield(Character,Weapon ) ->
        has(Character,weapon,Weapon).

    weapon:enchanted(Weapon,Ability) ->
         has(Weapon,ability, Ability).

    ability:price(Ability,Cost) ->
         has(Ability,cost,Cost).

Which would disguise your problem into something more "object oriented":

    Character2 =
character:wield(Character,
weapon:enchanted(of(Character,weapon),ability:price(of(of(Character,weapon),ability),123))).

But the entire notion of nested structures for this sort of design would be
wrong in most languages as the exact semantics rely upon wether or not you
are intending for just this instance of this Character's weapon's ability's
cost to be modified, or you are modifying the cost of the ability across
the game (due to ability being a reference to a shared data structure, or
just intending all instances of this weapon to be modified (due to ability
being a substructure of weapon itself AND weapon is a reference to a shared
structure).

In either of those two cases, this approach will fail entirely, as it will
construct clean proplists and only modify the cost of this specific
character's individual weapon's specific ability cost.  So once again:

   Character.weapon.ability.cost = 123

Is very difficult to qualify within your assumptions, because we don't know
the structural ramifications of the . operator.

Part of the reason I brought up process dictionaries and processes is I've
been playing around with structuring game data using them:

   https://github.com/cthulhuology/eoom/blob/master/object.erl

Where you can send "objects" messages to do these things:

1> l(object).
{module,object}
2> O = object:new().
<0.34.0>
3> O ! [ self(), does, hello, fun() -> io:format("hello world~n") end ].
[<0.31.0>,does,hello,#Fun<erl_eval.20.111823515>]
4>  O ! hello.
hello world
hello
5>

The fun thing here is sending funs to objects living out in the servers and
modifying their behavior at a distance.  So in this scheme, I would tend to
do something like:

Character ! [ self(), wielding ].

Which would respond with a message send of its own

Sender ! [ wielding, get(weapon) ].

In the interrogating process's wielding method I'd then send the Weapon:

Weapon ! [ self(), price, 123 ].

And it would set its own cost in it's price method.

So there's a lot of ways to skin this cat based on the structure of how you
hide your properties.

Dave

-- 
-=-=-=-=-=-=-=-=-=-=- http://blog.dloh.org/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130125/6b453442/attachment.html>


More information about the erlang-questions mailing list