# Newbie question: Defining a numeric type

Discussion in 'Ruby' started by Seebs, Nov 15, 2009.

1. ### SeebsGuest

I have a type which has a bit of internal magic, but fundamentally, I want
it to behave for most purposes like the value it yields from to_i/to_int.

Basically, is there a way to avoid having to write +, -, etcetera, when
in each case it'd be:
def <op>(other)
self.to_i <op> other
end

I think I'm thinking something like the Comparable mixin; sort of a
"I have a to_i, make me a number" module.

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

Seebs, Nov 15, 2009

2. ### Mario CamouGuest

Re: Newbie question: Defining a numeric type

Have a look at Forwardable

On Monday, November 16, 2009, Seebs <> wrote:
> I have a type which has a bit of internal magic, but fundamentally, I wan=

t
> it to behave for most purposes like the value it yields from to_i/to_int.
>
> Basically, is there a way to avoid having to write +, -, etcetera, when
> in each case it'd be:
> =A0 =A0 =A0 =A0def <op>(other)
> =A0 =A0 =A0 =A0 =A0self.to_i <op> other
> =A0 =A0 =A0 =A0end
>
> I think I'm thinking something like the Comparable mixin; sort of a
> "I have a to_i, make me a number" module.
>
> -s
> --
> Copyright 2009, all wrongs reversed. =A0Peter Seebach / usenet-nospam@see=

bs.net
> http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
> http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
>
>

--=20
-Mario.

--
I want to change the world but they won't give me the source code.

Mario Camou, Nov 16, 2009

3. ### Marnen Laibow-KoserGuest

Seebs wrote:
> I have a type which has a bit of internal magic, but fundamentally, I
> want
> it to behave for most purposes like the value it yields from
> to_i/to_int.

Does it need to be a class of its own? You could use a module and just
include it where necessary:

module Magical
def magic
...
end
end
...
...
@val = 5
class << @val
include Magical
end
@val.magic

>
> Basically, is there a way to avoid having to write +, -, etcetera, when
> in each case it'd be:
> def <op>(other)
> self.to_i <op> other
> end
>

If you don't like the first solution, try:

[:+, :*, :-, :/, :%].each do |op|
define_method op {|other| self.send op, other}
end

You could wrap this in a module too.

> I think I'm thinking something like the Comparable mixin; sort of a
> "I have a to_i, make me a number" module.
>
> -s

Best,
--
Marnen Laibow-Koser
http://www.marnen.org

--
Posted via http://www.ruby-forum.com/.

Marnen Laibow-Koser, Nov 16, 2009
4. ### Marnen Laibow-KoserGuest

Seebs wrote:
> I have a type which has a bit of internal magic, but fundamentally, I
> want
> it to behave for most purposes like the value it yields from
> to_i/to_int.

Does it need to be a class of its own? You could use a module and just
include it where necessary:

module Magical
def magic
...
end
end
...
...
@val = 5
class << @val
include Magical
end
@val.magic

>
> Basically, is there a way to avoid having to write +, -, etcetera, when
> in each case it'd be:
> def <op>(other)
> self.to_i <op> other
> end
>

If you don't like the first solution, try:

[:+, :*, :-, :/, :%].each do |op|
define_method op {|other| self.to_i.send op, other}
end

You could wrap this in a module too.

> I think I'm thinking something like the Comparable mixin; sort of a
> "I have a to_i, make me a number" module.
>
> -s

Best,
--
Marnen Laibow-Koser
http://www.marnen.org

--
Posted via http://www.ruby-forum.com/.

Marnen Laibow-Koser, Nov 16, 2009
5. ### SeebsGuest

On 2009-11-16, Marnen Laibow-Koser <> wrote:
> Does it need to be a class of its own?

I think it makes more sense that way. It's a category of objects which
have common additional methods they support, but which can be used in nearly
any context where you could use an integer.

> If you don't like the first solution, try:
>
> [:+, :*, :-, :/, :%].each do |op|
> define_method op {|other| self.to_i.send op, other}
> end
>
> You could wrap this in a module too.

Could, but...

The suggestion to try Forwardable got me to find SimpleDelegator, which
turns out to work beautifully.

Basically, I'm doing a roguelike mostly for fun and/or as a learning
exercise, and I wanted a way to encode "stats" -- things like strength
or intelligence, which characters have. Stats might have temporary
modifiers, or remember their highest previous value, or whatever... But
90% of the time, you just want to refer to them and get the value
they currently have. Making the user write "player.str.current_value"
is annoying; I'd rather just use "player.str". So having that delegate
to an internal member which really is just an integer works; then, whenever
that value changes, I point the delegator at it, and Everything Just
Works.

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

Seebs, Nov 16, 2009
6. ### Marnen Laibow-KoserGuest

Seebs wrote:
> On 2009-11-16, Marnen Laibow-Koser <> wrote:
>> Does it need to be a class of its own?

>
> I think it makes more sense that way. It's a category of objects which
> have common additional methods they support, but which can be used in
> nearly
> any context where you could use an integer.

Then they should most likely be Integers. Extend them either with
module inclusion or by subclassing.

>
>> If you don't like the first solution, try:
>>
>> [:+, :*, :-, :/, :%].each do |op|
>> define_method op {|other| self.to_i.send op, other}
>> end
>>
>> You could wrap this in a module too.

>
> Could, but...
>
> The suggestion to try Forwardable got me to find SimpleDelegator, which
> turns out to work beautifully.

Yeah, but it's probably not conceptually right for this case. Have you
classes?

>
> Basically, I'm doing a roguelike mostly for fun and/or as a learning
> exercise, and I wanted a way to encode "stats" -- things like strength
> or intelligence, which characters have. Stats might have temporary
> modifiers, or remember their highest previous value, or whatever... But
> 90% of the time, you just want to refer to them and get the value
> they currently have. Making the user write "player.str.current_value"
> is annoying; I'd rather just use "player.str". So having that delegate
> to an internal member which really is just an integer works; then,
> whenever
> that value changes, I point the delegator at it, and Everything Just
> Works.

If you use actual Integers as I suggested above, everything will Just
Work with less effort, and your design will be clearer.

>
> -s

Best,
--
Marnen Laibow-Koser
http://www.marnen.org

--
Posted via http://www.ruby-forum.com/.

Marnen Laibow-Koser, Nov 16, 2009
7. ### Brian CandlerGuest

Seebs wrote:
> I think I'm thinking something like the Comparable mixin; sort of a
> "I have a to_i, make me a number" module.

You could just delegate to the number:

class Foo
def initialize(n)
@n = n
end
def to_int
@n
end
def method_missing(*args)
to_int.send(*args)
end
end

f = Foo.new(12)
puts f + 3
puts 2 + f

Note that there is a subtle distinction between to_int and to_i, as
there is between to_str and to_s. I think you want to_int here, since
you are declaring that your object is, to all intents and purposes, an
integer.

You could also look at the #coerce method, but I don't think it's needed
here.
--
Posted via http://www.ruby-forum.com/.

Brian Candler, Nov 16, 2009
8. ### Marnen Laibow-KoserGuest

Seebs wrote:
> On 2009-11-16, Marnen Laibow-Koser <> wrote:
>> Seebs wrote:
>>> I think it makes more sense that way. It's a category of objects which
>>> have common additional methods they support, but which can be used in
>>> nearly
>>> any context where you could use an integer.

>
>> Then they should most likely be Integers. Extend them either with
>> module inclusion or by subclassing.

>
> Hmm. I tried subclassing, but perhaps incorrectly. The problem is that
> it really is, internally, an object with several integers, but unless
> you
> know that and care about it, all you need is one particular one of those
> integers.

Oh, then that's a different story. In this case, delegation is probably
the right thing to do.

>
>> Yeah, but it's probably not conceptually right for this case. Have you
>> been following the thread about using mixins rather than declaring new
>> classes?

>
> Only sort of.
>
>> If you use actual Integers as I suggested above, everything will Just
>> Work with less effort, and your design will be clearer.

>
> around it. So far as I can tell, unless the integer is a Bignum, it'll
> be a Fixnum -- which means that any two things with the same value
> are the same object, and so on.
>
> But I don't want any two statistics which currently have the same
> apparent
> value to be the same object -- because I need to be able to, say, tack
> on
> a modifier to one of them and have it not affect the other.

Sure. I didn't realize you were doing things like that. And you're
right that the singleton nature of Bignums makes them less flexible in
this regard.

>
> As an example, some hypothetical object might do something like:
>
> x = Stat.new(10)
> y = Stat.new(10)
>
>
> At this point, "x + 1" should be 16, and "y + 1" should be 11. If I
> tacked
> on a "+3" modifier to x, x would report itself as 18... But internally,
> it's a 15 and a +3. 18 is just its value for most purposes.
>
> I can't figure out how to express that by subclassing Integer.

It's probably not worth it. I didn't understand your structure
originally.

> The stat
> has several integers, although one of them is the one you probably want
> if
> you're trying to perform arithmetic on it.

Brian's suggestion of #coerce may be a good one.

>
> (Note the "adjust_to" -- you can't, for obvious reasons, assign a new
> value with =. Things which have stats define the attr= for those stats

Philosophical point: many people (myself included, I think) believe that
unlike entity objects (say, Player in your game), value objects should
be immutable. This means

class Stat
@base = n
# good:
Stat.new(n, @modifier)
end
end

See http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable . Among other
things, this means you never have to worry about modifying an object
referred to in multiple places.

>
> -s

Best,
--
Marnen Laibow-Koser
http://www.marnen.org

--
Posted via http://www.ruby-forum.com/.

Marnen Laibow-Koser, Nov 16, 2009
9. ### SeebsGuest

On 2009-11-16, Marnen Laibow-Koser <> wrote:
>> (Note the "adjust_to" -- you can't, for obvious reasons, assign a new
>> value with =. Things which have stats define the attr= for those stats

> Philosophical point: many people (myself included, I think) believe that
> unlike entity objects (say, Player in your game), value objects should
> be immutable. This means
>
> class Stat
> @base = n
> # good:
> Stat.new(n, @modifier)
> end
> end
>
> See http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable . Among other
> things, this means you never have to worry about modifying an object
> referred to in multiple places.

In this case, I think the correct model is that this isn't really a value
object, it's just an object which has a value. Imagine that I wanted to
talk about "my paycheck". Well, there's a base salary, and there's various
taxes and deductions and withholding... But except when I'm doing the tax
accounting, all I *really* care about is the take-home pay, so if I
refer to "salary" I probably mean the output value of all those calculations.

Basically, if someone else has a reference to a specific stat, and it
changes, I think they DO want to see the now-changed value.

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

Seebs, Nov 16, 2009
10. ### SeebsGuest

On 2009-11-16, Marnen Laibow-Koser <> wrote:
>> (Note the "adjust_to" -- you can't, for obvious reasons, assign a new
>> value with =. Things which have stats define the attr= for those stats

> Philosophical point: many people (myself included, I think) believe that
> unlike entity objects (say, Player in your game), value objects should
> be immutable. This means
>
> class Stat
> @base = n
> # good:
> Stat.new(n, @modifier)
> end
> end
>
> See http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable . Among other
> things, this means you never have to worry about modifying an object
> referred to in multiple places.

In this case, I think the correct model is that this isn't really a value
object, it's just an object which has a value. Imagine that I wanted to
talk about "my paycheck". Well, there's a base salary, and there's various
taxes and deductions and withholding... But except when I'm doing the tax
accounting, all I *really* care about is the take-home pay, so if I
refer to "salary" I probably mean the output value of all those calculations.

Basically, if someone else has a reference to a specific stat, and it
changes, I think they DO want to see the now-changed value.

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

Seebs, Nov 16, 2009
11. ### Marnen Laibow-KoserGuest

Seebs wrote:
> On 2009-11-16, Marnen Laibow-Koser <> wrote:
>>> (Note the "adjust_to" -- you can't, for obvious reasons, assign a new
>>> value with =. Things which have stats define the attr= for those stats

>
>> end
>> end
>>
>> See http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable . Among other
>> things, this means you never have to worry about modifying an object
>> referred to in multiple places.

>
> In this case, I think the correct model is that this isn't really a
> value
> object, it's just an object which has a value.

I think you are likely wrong. But there's a simple conceptual test you
can apply:

a = Stat.new(5)
b = Stat.new(5)

Should a == b return true or false?

If false, then this is probably not a value object in the conventional
sense.

If true, then it probably is.

> Imagine that I wanted to
> talk about "my paycheck". Well, there's a base salary, and there's
> various
> taxes and deductions and withholding... But except when I'm doing the
> tax
> accounting, all I *really* care about is the take-home pay, so if I
> refer to "salary" I probably mean the output value of all those
> calculations.

stat block, whereas the individual Stat objects seem to be analogous to
the dollar amounts on each like of the paycheck -- and those are
certainly value objects.

>
> Basically, if someone else has a reference to a specific stat, and it
> changes, I think they DO want to see the now-changed value.
>

And I think you're probably wrong.

john = Character.new
john.strength = Stat.new(15)
mary = Character.new
mary.strength = john.strength
mary.strength += 1

Now, what should john.strength be? 15 or 16?

> -s

Best,
--
Marnen Laibow-Koser
http://www.marnen.org

--
Posted via http://www.ruby-forum.com/.

Marnen Laibow-Koser, Nov 16, 2009
12. ### SeebsGuest

On 2009-11-16, Marnen Laibow-Koser <> wrote:
> a = Stat.new(5)
> b = Stat.new(5)
>
> Should a == b return true or false?

> If false, then this is probably not a value object in the conventional
> sense.

> If true, then it probably is.

Hmm.

I would think it should return true.

> Poor analogy. I think your paycheck is like your character's entire
> stat block, whereas the individual Stat objects seem to be analogous to
> the dollar amounts on each like of the paycheck -- and those are
> certainly value objects.

An individual stat might have:
base value 10
modifier (racial, no duration) +3
modifier (training, no duration) +2
modifier (drunk, duration 15 turns) -1

That's "a 14". It is *equal to* another stat which has a base value of 14
and no modifiers. But it's not the same *thing* as that other stat.

> And I think you're probably wrong.
>
> john = Character.new
> john.strength = Stat.new(15)
> mary = Character.new
> mary.strength = john.strength
> mary.strength += 1
>
> Now, what should john.strength be? 15 or 16?

15. But you don't copy stats -- you use their values. So what really
happens is that mary defines strength= such that it applies modifiers
to mary.strength.

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.

Hmm.

So, thinking about it, it seems like what I'm getting to is that really,
the "Stat" class is largely internal to characters. It's a way to express
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.)
For the purposes of nearly any possible interaction, john.strength is
just the value 15.

You're asking some really good questions here, thanks.

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

Seebs, Nov 16, 2009
13. ### Marnen Laibow-KoserGuest

Seebs wrote:
> On 2009-11-16, Marnen Laibow-Koser <> wrote:
>> a = Stat.new(5)
>> b = Stat.new(5)
>>
>> Should a == b return true or false?

>
>> If false, then this is probably not a value object in the conventional
>> sense.

>
>> If true, then it probably is.

>
> Hmm.
>
> I would think it should return true.

So would I.

>
>> Poor analogy. I think your paycheck is like your character's entire
>> stat block, whereas the individual Stat objects seem to be analogous to
>> the dollar amounts on each like of the paycheck -- and those are
>> certainly value objects.

>
> An individual stat might have:
> base value 10
> modifier (racial, no duration) +3
> modifier (training, no duration) +2
> modifier (drunk, duration 15 turns) -1
>
> That's "a 14". It is *equal to* another stat which has a base value of
> 14
> and no modifiers. But it's not the same *thing* as that other stat.

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?

>
>> And I think you're probably wrong.
>>
>> john = Character.new
>> john.strength = Stat.new(15)
>> mary = Character.new
>> mary.strength = john.strength
>> mary.strength += 1
>>
>> Now, what should john.strength be? 15 or 16?

>
> 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.

> So what really
> happens is that mary defines strength= such that it applies modifiers
> to mary.strength.

Or simply creates a new immutable value object, which will save some

>
> 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.

>
> Hmm.
>
> So, thinking about it, it seems like what I'm getting to is that really,
> the "Stat" class is largely internal to characters. It's a way to
> express
> 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? 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.

> For the purposes of nearly any possible interaction, john.strength is
> just the value 15.

The easiest way to achieve that is with conversion and/or coercion.

>
> You're asking some really good questions here, thanks.
>
> -s

You're welcome! These are questions I struggle with as well -- I like
to learn by teaching.
Best,
--
Marnen Laibow-Koser
http://www.marnen.org

--
Posted via http://www.ruby-forum.com/.

Marnen Laibow-Koser, Nov 16, 2009
14. ### SeebsGuest

On 2009-11-16, Marnen Laibow-Koser <> 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 /
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Seebs, Nov 17, 2009
15. ### Marnen Laibow-KoserGuest

Seebs wrote:
> On 2009-11-16, Marnen Laibow-Koser <> wrote:
>> 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.

But you yourself said:

[...]
> That's "a 14". It is *equal to* another stat which has a base value of

14
> and no modifiers. But it's not the same *thing* as that other stat.

== means "conceptually the same thing", I think. Not necessarily the
same object reference -- but equivalent. So I actually don't think you
want a==c to be true. You may want a==10 to be true, but that's a
different story.

>
>>> 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.

OK, think of it like this: if their values are the same, they are
considered equal. Stat.new(5) == Stat.new(5) even though Stat.new(5)
doesn't equal? Stat.new(5) -- that is, they are equal even though
they're not necessarily the same object.

How you define "values are the same" is up to you. I think it's best to
consider it as meaning total equality for both base and modifiers.

>
> 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.

Right. But two stats which have the same base and modifiers *are* the
same thing, aren't they? There's no reason to know whether they're
different objects in the VM -- for all practical purposes, they are *the
same thing*. And that fact (if it is a fact) means that we're talking

[...]
> 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

That's not the way Ruby references work. You can obtain a reference to
the object returned by john.strength at a given time, but you can't know
whether john.strength will always return that same object.

In other words, you could call john.strength.object_id and get a value
(let's say 12345). If you later call john.strength.object_id, the
returned value might or might not be 12345. The caller should make no
assumptions in this regard.

>-- 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".

There is no such thing in Ruby, as I explained above. There is nothing
really to be gained by keeping the object_id the same.

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

And really no way to do it. (Even if they do figure out a way, that's
abuse of your interface. They shouldn't expect it to work.)

[...]
>> 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?

Yes. That is the best way of handling value objects -- in fact, it's
the way Ruby handles Fixnums!

irb(main):001:0> a = 1
=> 1
irb(main):002:0> a.object_id
=> 3
irb(main):003:0> a += 5
=> 6
irb(main):004:0> a.object_id
=> 13

Object 1 is the Fixnum 1, and object 13 is the Fixnum 6. When the value
of a changes, the variable a holds an entirely different object
reference.

>
> 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.

Then maybe a statistic should be composed of several value objects. I
was operating under the assumption that it's just a base Fixnum and a
Hash containing a few modifier Fixnums. What else is there?

> 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.

Right -- probably a Fixnum.

>
> 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,

Which you can do with delegation and coercion.

> and bypasses the
> large, complicated, mutable object.

From what you've described, Stat isn't large and complicated. What's

>
> -s

Best,
--
Marnen Laibow-Koser
http://www.marnen.org

--
Posted via http://www.ruby-forum.com/.

Marnen Laibow-Koser, Nov 17, 2009
16. ### SeebsGuest

On 2009-11-17, Marnen Laibow-Koser <> wrote:
>== means "conceptually the same thing", I think. Not necessarily the
> same object reference -- but equivalent.

Hmm.

I guess I think of == as more like "functionally the same". Two 14s function
the same way. If the question is "who is stronger", then if both characters
have a current functional strength of 14, it's a tie.

But that doesn't make them the same object.

Basically: 14.0 == 14. That doesn't mean they're the same thing, because
obviously they're different things. And they're not even quite equivalent;
15 / 14.0 is not the same as 15 / 14. But they're still equal, because they
have the same value.

> How you define "values are the same" is up to you. I think it's best to
> consider it as meaning total equality for both base and modifiers.

I don't, though, because the only reason to be comparing two values is to
see whether one is larger than the other -- say, whether one creature is
stronger than another.

> Right. But two stats which have the same base and modifiers *are* the
> same thing, aren't they?

I don't think so. Even if john and mary both have the same base strength,
and the same modifiers, they're not the same thing -- making john stronger
doesn't make mary stronger.

> That's not the way Ruby references work. You can obtain a reference to
> the object returned by john.strength at a given time, but you can't know
> whether john.strength will always return that same object.

Right -- which is why my initial plan was to commit that, after initialize(),
john.strength DOES always yield the same object, no matter what changes

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

> Yes. That is the best way of handling value objects -- in fact, it's
> the way Ruby handles Fixnums!

This sounds extremely expensive for an extremely commonplace thing. In
an ordinary turn of a game, I might have thirty or forty modifiers which
change, meaning that I'd be duplicating-but-modifying non-trivial object
trees thirty or forty times.

> Object 1 is the Fixnum 1, and object 13 is the Fixnum 6. When the value
> of a changes, the variable a holds an entirely different object
> reference.

Yes, I know that.

But I don't think a stat is a value. I think it's a complicated model, which
happens to yield a value.

> Then maybe a statistic should be composed of several value objects. I
> was operating under the assumption that it's just a base Fixnum and a
> Hash containing a few modifier Fixnums. What else is there?

History of previous values (in some cases), and the modifiers aren't
fixnums; they're name/value pairs probably plus other traits such as
a duration (some expire, some don't). There will probably be more
tweaks to that over time.

> From what you've described, Stat isn't large and complicated. What's

As time goes on, stats are expected to be much more complicated. A stat
will likely have its original starting base value, its highest recorded base
value, and a set of modifiers (which may change quite often). Possibly more
things beyond those.

So right now, I think it is probably nearly-sanest for me to have it delegate
nearly everything to the fixnum current value, which really is a value object.
So it isn't a value, but it delegates to one.

Basically, anything that has internal state to keep track of which is not part
of how you use it strikes me as not really being a value, even if it looks
like one from the outside.

That said!

I am thinking that perhaps it should *present* as immutable -- that is, I
should not define john.strength = 15 in any way, but rather, if you want to
ask it to change its value, you have to send it messages. So instead of
john.strength += 1, you'd write john.strength.adjust_by(1).

Hmm. I suppose the thing, then, would be to simply not provide a strength=
method for the things that have stats.

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

Seebs, Nov 17, 2009
17. ### Marnen Laibow-KoserGuest

Seebs wrote:
[...]
>> Right. But two stats which have the same base and modifiers *are* the
>> same thing, aren't they?

>
> I don't think so. Even if john and mary both have the same base
> strength,
> and the same modifiers, they're not the same thing -- making john
> stronger
> doesn't make mary stronger.

I didn't say the same object -- I said the same *thing*.
a = Stat.new(15, -2)
b = Stat.new(15, -2)
It doesn't matter in the slightest whether a.object_id == b.object_id.
Regardless, a and b are *the same thing* to all intents and purposes --
and you can tell that, in part, precisely because the object_id is
irrelevant. John's strength isn't the same thing as Mary's strength,
but that's a very different issue. The English concept "John's strength
(in the abstract)" is equivalent to the Ruby method call john.strength.
The English concept "the concrete value that, for the moment, represents
John's strength" is equivalent to the return value from that method
call. You're confusing the method with its return value. The
difference is subtle but important.

English: John's strength, in the abstract, isn't the same thing as
Mary's strength in the abstract.
Ruby: john.methodstrength) != mary.methodstrength)

English: The current value of John's strength happens to be equal to the
current value of Mary's strength.
Ruby: john.strength == mary.strength

Does this make sense?

>
>> That's not the way Ruby references work. You can obtain a reference to
>> the object returned by john.strength at a given time, but you can't know
>> whether john.strength will always return that same object.

>
> Right -- which is why my initial plan was to commit that, after
> initialize(),
> john.strength DOES always yield the same object, no matter what changes
> are made to its value.

Why? There's no point to doing so as far as I can see. Even if it were
a Fixnum, it would already be yielding different objects every time it
changed. The client should make no assumptions about
john.strength.object_id.

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

>
>> Yes. That is the best way of handling value objects -- in fact, it's
>> the way Ruby handles Fixnums!

>
> This sounds extremely expensive for an extremely commonplace thing. In
> an ordinary turn of a game, I might have thirty or forty modifiers which
> change, meaning that I'd be duplicating-but-modifying non-trivial object
> trees thirty or forty times.

It may sound expensive, but it really is the best way of handling value
objects. This is how classes like Fixnum, Date, and BigDecimal work.
(Actually, Fixnum uses the Flyweight pattern under the hood; the others
might also.)

>
>> Object 1 is the Fixnum 1, and object 13 is the Fixnum 6. When the value
>> of a changes, the variable a holds an entirely different object
>> reference.

>
> Yes, I know that.
>
> But I don't think a stat is a value. I think it's a complicated model,
> which
> happens to yield a value.
>
>> Then maybe a statistic should be composed of several value objects. I
>> was operating under the assumption that it's just a base Fixnum and a
>> Hash containing a few modifier Fixnums. What else is there?

>
> History of previous values (in some cases), and the modifiers aren't
> fixnums; they're name/value pairs

Really? You're not just doing
@modifiers = {:racial => 2, :class => 1, :armor => -1}?

> probably plus other traits such as
> a duration (some expire, some don't).

Does that really belong in the values itself? I'd tend to think not;
rather, that probably belongs in your event system.

> There will probably be more
> tweaks to that over time.

OK, then this is getting more complex than a simple value object. If
you want history, maybe you should have a separate StatValue object, or
simply a hash.

But if you want history, then the StatValue object or whatever you wind
up using will probably have to be immutable anyway, so you can be sure

>
>> From what you've described, Stat isn't large and complicated. What's

>
> As time goes on, stats are expected to be much more complicated.

Then refactor your design at that time. Design for what you have now,
rather than predicting the future. Remember YAGNI.

> A stat
> will likely have its original starting base value, its highest recorded
> base
> value, and a set of modifiers (which may change quite often). Possibly
> more
> things beyond those.

Since you don't know yet, don't design yet for them (your future plans
could easily change). Design a model that works for what you actually
have, and be ready to change it as necessary.

>
> So right now, I think it is probably nearly-sanest for me to have it
> delegate
> nearly everything to the fixnum current value, which really is a value
> object.
> So it isn't a value, but it delegates to one.
>
> Basically, anything that has internal state to keep track of which is
> not part
> of how you use it strikes me as not really being a value, even if it
> looks
> like one from the outside.

Largely correct, although I can think of exceptions. You'll probably
want to break this down into a composed object containing one or more
value objects.

>
> That said!
>
> I am thinking that perhaps it should *present* as immutable -- that is,
> I
> should not define john.strength = 15 in any way, but rather, if you want
> to
> ask it to change its value, you have to send it messages. So instead of
> john.strength += 1, you'd write john.strength.adjust_by(1).

No need. The former is a lot friendlier. You can always redefine
Character#strength= .

>
> Hmm. I suppose the thing, then, would be to simply not provide a
> strength=
> method for the things that have stats.
>

That strikes me as silly. There's no reason that the client class
should care whether your strength= method *really* does an assignment
operation.

Remember, one of the nice things about OO programming is that interface
and implementation needn't resemble each other in the slightest.
> -s

Best,
--
Marnen Laibow-Koser
http://www.marnen.org

--
Posted via http://www.ruby-forum.com/.

Marnen Laibow-Koser, Nov 17, 2009
18. ### SeebsGuest

On 2009-11-17, Marnen Laibow-Koser <> wrote:
> I didn't say the same object -- I said the same *thing*.
> a = Stat.new(15, -2)
> b = Stat.new(15, -2)
> It doesn't matter in the slightest whether a.object_id == b.object_id.
> Regardless, a and b are *the same thing* to all intents and purposes --
> and you can tell that, in part, precisely because the object_id is
> irrelevant.

Perhaps, but (15, -2) and (14, -1) are also *equal*, even though they're
obviously different things.

Two fives equal a ten. When I am talking about money, all I care about
is the net value, not the internal representation (coins or bills). Unless
I have to deal with a vending machine.

But 99% of the time, 10==10 is the correct interpretation of a comparison
between two fives and a ten.

> call. You're confusing the method with its return value. The
> difference is subtle but important.

Hmm.

Oh, heyyyyy.

Okay, so one option would be:
def str
@str.to_i
end

In short, just return the value rather than the object I'm using to model
it.

The problem is, I sort of want to be able to do things like:

Because really, the fact that str is a stat *is* part of the intended
published interface.

It's just that, if you aren't doing something uniquely stat-like to a
stat, you just want its integer value.

> English: John's strength, in the abstract, isn't the same thing as
> Mary's strength in the abstract.
> Ruby: john.methodstrength) != mary.methodstrength)
>
> English: The current value of John's strength happens to be equal to the
> current value of Mary's strength.
> Ruby: john.strength == mary.strength
>
> Does this make sense?

Yup.

> Why? There's no point to doing so as far as I can see. Even if it were
> a Fixnum, it would already be yielding different objects every time it
> changed. The client should make no assumptions about
> john.strength.object_id.

Not as a specified interface that people should rely on, but rather, as an
implementation choice -- it seems crazy to me to regenerate whole object-trees
frequently.

>> This sounds extremely expensive for an extremely commonplace thing. In
>> an ordinary turn of a game, I might have thirty or forty modifiers which
>> change, meaning that I'd be duplicating-but-modifying non-trivial object
>> trees thirty or forty times.

> It may sound expensive, but it really is the best way of handling value
> objects. This is how classes like Fixnum, Date, and BigDecimal work.
> (Actually, Fixnum uses the Flyweight pattern under the hood; the others
> might also.)

None of those classes are complicated trees containing five or ten or
thirty other objects, though, are they?

>> History of previous values (in some cases), and the modifiers aren't
>> fixnums; they're name/value pairs

> Really? You're not just doing
> @modifiers = {:racial => 2, :class => 1, :armor => -1}?

Modifier is a class too, which can handle things like counting down its
duration, etcetera.

And a stat has a handful of them.

>> probably plus other traits such as
>> a duration (some expire, some don't).

> Does that really belong in the values itself? I'd tend to think not;
> rather, that probably belongs in your event system.

It seems to me that the knowledge that a modifier expires is best handled
by embedding it in the modifier.

> But if you want history, then the StatValue object or whatever you wind
> up using will probably have to be immutable anyway, so you can be sure

Ahh, but I don't necessarily care whether it's accurate, just whether I
have a record.

For a concrete example: A lot of games would have, say, a strength stat,
and things that can lower your strength. Then you find a "potion of
restore strength", which restores your strength to its highest previous
value.

To my mind, this is the kind of thing that should be handled entirely
by the stat object. It's not john's job to know what his highest score
was for a given stat; it's the stat's job to know what its highest score
was.

> Then refactor your design at that time. Design for what you have now,
> rather than predicting the future. Remember YAGNI.

In this case, though, I really do know that I need a fair bit of this.
The ability to damage and restore stats is pretty much essential to a
roguelike.

> Since you don't know yet, don't design yet for them (your future plans
> could easily change). Design a model that works for what you actually
> have, and be ready to change it as necessary.

Yeah, but changing this into an immutable object is a lot MORE work. So
I'm not sure I should put extra work into making the object less flexible
on the off chance that I won't later not need to have done that work.

> Largely correct, although I can think of exceptions. You'll probably
> want to break this down into a composed object containing one or more
> value objects.

I think so.

> No need. The former is a lot friendlier. You can always redefine
> Character#strength= .

True.

> That strikes me as silly. There's no reason that the client class
> should care whether your strength= method *really* does an assignment
> operation.

True.

Hmm.

So yeah, I think at this point, I really do want a complicated composite
object, which happens to delegate to a value object which has traits which
are useful for my purposes -- in this case, almost certainly a fixnum.

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

Seebs, Nov 17, 2009
19. ### Marnen Laibow-KoserGuest

Seebs wrote:
> On 2009-11-17, Marnen Laibow-Koser <> wrote:
>> I didn't say the same object -- I said the same *thing*.
>> a = Stat.new(15, -2)
>> b = Stat.new(15, -2)
>> It doesn't matter in the slightest whether a.object_id == b.object_id.
>> Regardless, a and b are *the same thing* to all intents and purposes --
>> and you can tell that, in part, precisely because the object_id is
>> irrelevant.

>
> Perhaps, but (15, -2) and (14, -1) are also *equal*, even though they're
> obviously different things.
>
> Two fives equal a ten. When I am talking about money, all I care about
> is the net value, not the internal representation (coins or bills).
> Unless
> I have to deal with a vending machine.
>
> But 99% of the time, 10==10 is the correct interpretation of a
> comparison
> between two fives and a ten.

a = Cash.new(Array.new(2, Banknote.new(5, :usd)))
b = Cash.new([Banknote.new(10, :usd))
a.to_money = b.to_money
a.banknotes != b.banknotes
a ?== b # depends on your definition of equality.

>
>> call. You're confusing the method with its return value. The
>> difference is subtle but important.

>
> Hmm.
>
> Oh, heyyyyy.
>
> Okay, so one option would be:
> def str
> @str.to_i
> end
>
> In short, just return the value rather than the object I'm using to
> model
> it.

That would be the appropriate solution if you never wanted to expose the
Stat object.

>
> The problem is, I sort of want to be able to do things like:
>
> Because really, the fact that str is a stat *is* part of the intended
> published interface.

Then your clients will know that it's a Stat object, and expect to call
to_i on it. I don't see anything wrong with that; you can overload Stat
+ Fixnum and so on as we discussed earlier in this thread.

But if you really want automatic, you can have it:
class Stat
def to_int
self.to_i
end
end

(According to http://www.rubyfleebie.com/to_i-vs-to_int/ , to_int is
called automatically as necessary and will make your class act as an
Integer. to_i, of course, will not do that.)

[...]
>> Why? There's no point to doing so as far as I can see. Even if it were
>> a Fixnum, it would already be yielding different objects every time it
>> changed. The client should make no assumptions about
>> john.strength.object_id.

>
> Not as a specified interface that people should rely on, but rather, as
> an
> implementation choice -- it seems crazy to me to regenerate whole
> object-trees
> frequently.

For your use case, you're probably right. For real value objects, it's
a different story.

>
>>> This sounds extremely expensive for an extremely commonplace thing. In
>>> an ordinary turn of a game, I might have thirty or forty modifiers which
>>> change, meaning that I'd be duplicating-but-modifying non-trivial object
>>> trees thirty or forty times.

>
>> It may sound expensive, but it really is the best way of handling value
>> objects. This is how classes like Fixnum, Date, and BigDecimal work.
>> (Actually, Fixnum uses the Flyweight pattern under the hood; the others
>> might also.)

>
> None of those classes are complicated trees containing five or ten or
> thirty other objects, though, are they?

Fixnum probably isn't. Date probably contains about 5 other objects
(totally guessing here -- haven't looked at the implementation). The
BigDecimal library I wrote for Rubinius contained about 3-5 other
objects, but I don't know if MRI or JRuby does it the same way. The
Address class I wrote for Quorum ( http://quorum2.sourceforge.net )
contains about 6 fields in an immutable value object. Of course, I
rarely only need to modify one field in someone's address.

>
>>> History of previous values (in some cases), and the modifiers aren't
>>> fixnums; they're name/value pairs

>
>> Really? You're not just doing
>> @modifiers = {:racial => 2, :class => 1, :armor => -1}?

>
> Modifier is a class too, which can handle things like counting down its
> duration, etcetera.
>
> And a stat has a handful of them.

OK...*these* are your value object candidates, perhaps.

>
>>> probably plus other traits such as
>>> a duration (some expire, some don't).

>
>> Does that really belong in the values itself? I'd tend to think not;
>> rather, that probably belongs in your event system.

>
> It seems to me that the knowledge that a modifier expires is best
> handled
> by embedding it in the modifier.

It might be.

>
>> But if you want history, then the StatValue object or whatever you wind
>> up using will probably have to be immutable anyway, so you can be sure

>
> Ahh, but I don't necessarily care whether it's accurate, just whether I
> have a record.

If it's not accurate, then there's no point keeping a record.

>
> For a concrete example: A lot of games would have, say, a strength
> stat,
> and things that can lower your strength. Then you find a "potion of
> restore strength", which restores your strength to its highest previous
> value.
>
> To my mind, this is the kind of thing that should be handled entirely
> by the stat object. It's not john's job to know what his highest score
> was for a given stat; it's the stat's job to know what its highest score
> was.

That depends. A good argument could be made for having the Character
store its own history, and just having the Stats be values.

In either case, though, for this sort of functionality you don't
necessarily need a full-fledged history. All you need is something like
class Stat
def value=(new_value)
@max_value = [new_value, @value].max
@value = new value
end
end
If you're ambitious, you could put together something like
ActiveRecord's before_save (which is probably what I'd use for this in a
Rails app).

>
>> Then refactor your design at that time. Design for what you have now,
>> rather than predicting the future. Remember YAGNI.

>
> In this case, though, I really do know that I need a fair bit of this.
> The ability to damage and restore stats is pretty much essential to a
> roguelike.

Well, then you'll run into the design issues when you're ready for them.
For now, though, and at every future step, try to
http://c2.com/cgi/wiki?DoTheSimplestThingThatCouldPossiblyWork -- that
is, work with the state of the app *at that time*. I know premature
generalization is tempting, but it's not usually a good idea.

>
>> Since you don't know yet, don't design yet for them (your future plans
>> could easily change). Design a model that works for what you actually
>> have, and be ready to change it as necessary.

>
> Yeah, but changing this into an immutable object is a lot MORE work. So
> I'm not sure I should put extra work into making the object less
> flexible
> on the off chance that I won't later not need to have done that work.

Right. It's now clear that your stat object is too complex to be a
simple immutable value object, although some of its components might
well be.

>
>> Largely correct, although I can think of exceptions. You'll probably
>> want to break this down into a composed object containing one or more
>> value objects.

>
> I think so.
>
>> No need. The former is a lot friendlier. You can always redefine
>> Character#strength= .

>
> True.
>
>> That strikes me as silly. There's no reason that the client class
>> should care whether your strength= method *really* does an assignment
>> operation.

>
> True.
>
> Hmm.
>
> So yeah, I think at this point, I really do want a complicated composite
> object, which happens to delegate to a value object which has traits
> which
> are useful for my purposes -- in this case, almost certainly a fixnum.

I don't think delegation will work here -- for one thing, you may not
need to store the total value in any actual instance variable. Using
to_int or possibly coerce will work much better.

>
> -s

Best,
--
Marnen Laibow-Koser
http://www.marnen.org

--
Posted via http://www.ruby-forum.com/.

Marnen Laibow-Koser, Nov 17, 2009
20. ### SeebsGuest

On 2009-11-17, Marnen Laibow-Koser <> wrote:
>> The problem is, I sort of want to be able to do things like:

>> Because really, the fact that str is a stat *is* part of the intended
>> published interface.

> Then your clients will know that it's a Stat object, and expect to call
> to_i on it.

Except that it's extremely annoying to have an object where, out of five
hundred uses, four hundred and ninety six need an extra ".to_i".

> I don't see anything wrong with that; you can overload Stat
> + Fixnum and so on as we discussed earlier in this thread.

Yeah.

> But if you really want automatic, you can have it:
> class Stat
> def to_int
> self.to_i
> end
> end

> (According to http://www.rubyfleebie.com/to_i-vs-to_int/ , to_int is
> called automatically as necessary and will make your class act as an
> Integer. to_i, of course, will not do that.)

This turns out not to quite be the case, in experiments. If I do that,
it works most of the time, but as an example:
john.str + john.dex + john.con
doesn't work, because it can't figure out that ANY of them should be
integers. I also end up having to define a bunch of additional operators;
for instance, if I want to be able to write "john.str + 3", I have to define
+ for Stat, even though "3 + john.str" would probably do the right thing.

>> Modifier is a class too, which can handle things like counting down its
>> duration, etcetera.
>>
>> And a stat has a handful of them.

> OK...*these* are your value object candidates, perhaps.

Hmm. Well, probably not -- modifiers have internal state (duration, which I
was thinking to indicate as a turn counter) which they want to update. Maybe.
I could make them into values perhaps if I, say, calculated their expiration
rather than their duration. Then, if you refresh a modifier, you make a new
one with a later expiration. Hmm.

>> Ahh, but I don't necessarily care whether it's accurate, just whether I
>> have a record.

> If it's not accurate, then there's no point keeping a record.

There can be; see below.

> In either case, though, for this sort of functionality you don't
> necessarily need a full-fledged history.

Right. I pretty much meant a mini-history like that.

> Right. It's now clear that your stat object is too complex to be a
> simple immutable value object, although some of its components might
> well be.

I'm sort of liking the idea of making modifiers into immutable values. It
would actually make life simpler, I think.

> I don't think delegation will work here -- for one thing, you may not
> need to store the total value in any actual instance variable. Using
> to_int or possibly coerce will work much better.

Delegation empirically *does* work, although it may not be the most efficient
or best choice of how to do things. Stashing the total value in an instance
variable may be useful anyway; these things get looked up pretty often.

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

Seebs, Nov 17, 2009