On 2009-11-16, Marnen Laibow-Koser <marnen / marnen.org> wrote:
> Of course it isn't.  Here's how I see this working (for simplicity, I'll 
> just assume one modifier):
>
> a = Stat.new 10, 0
> b = Stat.new 10, 2
> c = Stat.new 12, -2
> d = Stat.new 12, -2
> c == d # true
> a == b # false
> a == c # false
> a.to_i == c.to_i # true

> Does that all seem right?

Hmm.

I would actually expect a==c to be true.  There's no point where I really
want to perform an object-identity test on them, so even then, I'm just
comparing their to_i values, which will ==, since they're both 10.

>> 15.  But you don't copy stats -- you use their values.  

> Right!  In other words, they're identified by their value, not by the 
> individual object reference.  Ergo, *they are value objects*, by 
> definition.

"identified" may not be the right term.

Two stats which yield the same result value may *compare* equal -- because
if you're comparing them you're just working with values.  But that doesn't
mean that they're the same thing.  The primary way you'd *identify* a stat
is by knowing which stat it is, for which entity.

So if something, for some reason, has intentionally obtained a reference
to john.strength, then it really does want to see the current value of
john.strength -- but that's the exceptional case, not the normal case, so
assigning it to mary.strength wouldn't do that.

>> In fact, in "john.strength = Stat.new(15)", what really happens is that
>> john does the same thing -- adjust the already-existing stat so that it 
>> will
>> have an effective value of 15.

> No.  If you call a constructor, you might as well use the object. :)

Except that people might already have, for some crazy reason, an intentional
reference into "the strength stat for john".

Although it occurs to me that there's really no REASON for them to ever do
that.

>> something that, in general, no one else should use.  (Not quite true;
>> you can query the modifiers that currently apply to a stat, for 
>> instance.)

> So you *do* want to do something like john.strength.modifiers[:racial], 
> right?

Maybe.

> If so, then the Stat class is not internal.  Personally, I think 
> that's fine -- a stat is not jet a simple number, and so you might as 
> well represent it with an appropriate value object.

So when the modifiers change, your solution would be to replace the entire
object, duplicating its whole set of modifiers and other state?

Hmm.

I guess my current thought is...  A statistic really IS an object of its
own with complicated internal state which changes over time.  It doesn't
make sense to replace and duplicate that potentially-quite-complicated
state.  However, 90% of references will end up not caring about any of that
state, and only wanting the object's final-value -- which really IS a
value object.

So it would make some sense to just always right john.strength.value, except
that this would get to be really annoying, and since 90% of usages are going
to be like that, I come up with the alternative:  Any reference to
john.strength in a context that looks like it might be arithmetic yields the
value, which is at any given time an immutable object, and bypasses the
large, complicated, mutable object.

-s
-- 
Copyright 2009, all wrongs reversed.  Peter Seebach / usenet-nospam / seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!