<br><br><div class="gmail_quote">On Thu, Jan 24, 2013 at 10:18 AM, Loïc Hoguin <span dir="ltr"><<a href="mailto:essen@ninenines.eu" target="_blank">essen@ninenines.eu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5"><br></div></div>
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.</blockquote>
<div><br></div><div>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:</div>
<div><br></div><div> of(Object,Property) -> proplists:get_value(Property,Object).</div><div><br></div><div> has(Object,Property,Value) -> [ { Property, Value } | proplists:delete(Property,Object) ].</div><div><br>
</div><div>Where due to the horrible nature of the beast Character.weapon.ability.cost is:</div><div><br></div><div> of(of(of(Character,weapon),ability),cost).</div><div><br></div><div>And the assignment Character.weapon.ability.cost := 123 is:</div>
<div><br></div><div> Character2 = has(Character,weapon, has(of(Character,weapon), ability), has(of(of(Character,weapon),ability), cost, 123))).</div><div><br></div><div>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":</div>
<div><br></div><div> character:wield(Character,Weapon ) -></div><div> has(Character,weapon,Weapon).</div><div><br></div><div> weapon:enchanted(Weapon,Ability) -></div><div> has(Weapon,ability, Ability).</div>
<div><br></div><div> ability:price(Ability,Cost) -></div><div> has(Ability,cost,Cost).</div><div><br></div><div>Which would disguise your problem into something more "object oriented":</div><div><br>
</div><div> Character2 = character:wield(Character, weapon:enchanted(of(Character,weapon),ability:price(of(of(Character,weapon),ability),123))).</div><div><br></div><div>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).</div>
<div><br></div><div>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:</div>
<div><br></div><div> Character.weapon.ability.cost = 123</div><div><br></div><div>Is very difficult to qualify within your assumptions, because we don't know the structural ramifications of the . operator. </div><div>
<br></div><div>Part of the reason I brought up process dictionaries and processes is I've been playing around with structuring game data using them:</div><div><br></div><div> <a href="https://github.com/cthulhuology/eoom/blob/master/object.erl">https://github.com/cthulhuology/eoom/blob/master/object.erl</a></div>
<div><br></div><div>Where you can send "objects" messages to do these things:</div><div><br></div><div>1> l(object).</div><div>{module,object}</div><div>2> O = object:new().</div><div><0.34.0></div><div>
3> O ! [ self(), does, hello, fun() -> io:format("hello world~n") end ]. </div><div>[<0.31.0>,does,hello,#Fun<erl_eval.20.111823515>]</div><div>4> O ! hello.</div><div>hello world</div><div>
hello</div><div>5> </div><div><br></div><div>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:</div>
<div><br></div><div>Character ! [ self(), wielding ].</div><div><br></div><div>Which would respond with a message send of its own</div><div><br></div><div>Sender ! [ wielding, get(weapon) ]. </div><div><br></div><div>In the interrogating process's wielding method I'd then send the Weapon:</div>
<div><br></div><div>Weapon ! [ self(), price, 123 ].</div><div><br></div><div>And it would set its own cost in it's price method.</div><div><br></div><div>So there's a lot of ways to skin this cat based on the structure of how you hide your properties.</div>
<div><br></div><div>Dave</div><div><br></div></div>-- <br>-=-=-=-=-=-=-=-=-=-=- <a href="http://blog.dloh.org/">http://blog.dloh.org/</a>