Well, first, it seems as if you might find it easier to keep the classes
for character creation and the actual game somewhat different. Have the
game read the JSON into a separate “model” class that keeps it away from
the complexities of character creation, and just lets it deal with the
resulting character? I don’t know.
Second, it seems to me that all your characters want to partake in all
your addon functionality. The use case for Decorator Pattern is rather
different. It’s popular in game design, but not usually used in that way,
but rather like this:
flora = Character.new(“Flora the elven druid”)
flora.exend Elf
flora.exend Druid
varian = Character.new(“Varian the dwarven undead druid”)
varian.extend Dwarf
varian.extend Undead
varian.extend Druid
(Apologies if the formatting is odd, Outlook is playing Silly Devils)
If I understand correctly, you might want to go to what Smalltalk used to
call “Method Classes” – where you farm off some of your functionality to a
helper class that does a job, returns a result, and then never gets called
again. It seems like your CharacterCreation might best be that sort of
class. But I don’t know it well enough to say for sure.
class Person
def initialize(name, strength)
@name, @strength = name, strength
@foo = ValueOfFooFigurerOuter.new(strength).go
end
end
In the above example, the Person class doesn’t have to care how @foo is
calculated. A helper class does that for it.
Hope that helps…
*From:* ruby-talk [mailto:ruby-talk-bounces@ruby-lang.org] *On Behalf Of *leam
hall
*Sent:* 19 July 2018 13:57
*To:* Ruby users
*Subject:* Re: Class that opens and adds variables to instances of
another class?
Hmm..good question. This stems from my Traveller stuff and the game I'm
writing, which have two different uses for the Person class. Here's the
logic:
1. Every instance of Person
Has a name, gender, and UPP. (character stats)
Can be stored in a language agnostic manner (using JSON)
2. CharacterCreation adds to an instance of Person
Adds physical description, personality
3. Careers add to the instance of person
Skills, rank, notes, money, "stuff"
A character can go through multiple careers.
4. FreeTrader (the game) uses a limited subset of the Person + Additional
stuff.
Ship position(role),
Game uses JSON
Uses Careers, might use CharacterCreation.
5. CharacterData (the database) stores as much information about each
character as possible.
Planning to use Hanami/Sinatra? and a MongoDB backend.
Used to track details of characters for games and books I'm writing.
FreeTrader and CharacterData are separate projects but I want to build
from the same Person base and extend from there. That's why the instance of
a Person might have some attributes and not others.
Leam
On Thu, Jul 19, 2018 at 6:12 AM, Andy Jones <Andy.Jones@jameshall.co.uk> > wrote:
You have to ask yourself: composition or mixin? The easiest way is with a
mixin, but it has limitations.
~~~~
module Engineer
def can_do_engines?; true; end
end
class Person
def initialize(name); @name = name; end
end
p = Person.new("fred")
p.extend Engineer
puts p.can_do_engines?
~~~~
Note that you decorate an object --- not a class. If you want to add to
the functionality of every instance of a class, I'm not sure that counts as
Decorator pattern?
If you want to do it with Composition, instead, have a look at the Ruby
documentation for Forwardable. (Sorry this is a bit rushed; chaotic
today...)
I think that this might be the article that originally clued me into
Decorator? Not sure: https://robots.thoughtbot.com/evaluating-alternative-
decorator-implementations-in
-----Original Message-----
From: ruby-talk [mailto:ruby-talk-bounces@ruby-lang.org] On Behalf Of
Leam Hall
Sent: 19 July 2018 10:59
To: Ruby users
Subject: Class that opens and adds variables to instances of another class?
I think I'm trying to figure out the Decorator pattern. What I want is
to have a <thing> that takes an instance of <something> and changes it.
The changes can include modifying and adding instance variables.
Haven't quite figured it out yet, thoughts?
Thanks!
Leam
Here's the error:
###
Traceback (most recent call last):
3: from test_decorator.rb:28:in `<main>'
2: from test_decorator.rb:28:in `new'
1: from test_decorator.rb:17:in `initialize'
test_decorator.rb:20:in `assign_role': undefined method `role=' for
#<Person:0x0000562e9a870978 @data={:name=>"Al"}> (NoMethodError)
###
Code:
###
1 class Person
2 def initialize(data)
3 @data = data
4 end
5 def name
6 @data[:name] || "Fred"
7 end
8 end
9
10 class Role
11 class Person
12 attr_accessor :role
13 end
14
15 def initialize(data)
16 @person = data[:person]
17 assign_role(data[:role])
18 end
19 def assign_role(role)
20 @person.role = role
21 end
22 end
23
24 data = {:name => 'Al'}
25
26 al = Person.new(data)
27 role_data = {:person => al, :role => 'Cadet'}
28 Role.new(role_data)
29 puts al.name
30 #al.role = "Cadet Sergeant"
###
Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>
Click here to view Company Information and Confidentiality Notice.<
http://www.jameshall.co.uk/index.php/small-print/email-disclaimer>
Please note that we have updated our privacy policy in line with new data
protection regulations. Please refer to our website to view the ways in
which we handle your data.
Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>
Click here to view Company Information and Confidentiality Notice.
<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer>
Please note that we have updated our privacy policy in line with new data
protection regulations. Please refer to our website to view the ways in
which we handle your data.
Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>