Encapsulating Information and Behavior without State

I

Intransition

This should prove an interesting topic. I am currently debating two
potential means of implementing the same thing. What I have are sets
of methods and data that I need to encapsulate in one fashion or
another --lets call those the "character" of a thing. But there is no
state involved. Now, if there were state involved, the obvious answer
is to create a class encapsulating the character --one class for each
type of character. But since there is not state, to implement those as
a class means Singleton Classes. And I know there is a general meme
out there that says singleton classes are not good.

Let's use this silliness as an example:

class Character
include Singleton
def type
self.class::TYPE
end
end

class DuckCharacter < Character
TYPE = :bird
def quack
puts "quack quack"
end
end

That's one approach. (Note, I could use a function module, but
module's singleton levels don't inherit, among other things, so I
think that option is too limited.)

The other approach is to create a DSL to instantiate the character as
object, eg.

thing :duck, :type => :bird

behavior :duck, :quack do |duck|
puts "quack quack"
end

where #thing would do something like:

def thing(name, attribs={})
things[name] = Character.new(name, attribs)
end

and #behavior would add a Proc to the Character instance.

The upside here, of course, is the upside of DSLs. It's concise and to
the point and reads well. On the downside it won't document well under
RDoc, and I don't get as much in the way of utilizing inheritance.

So that's the idea. Getting back to the main question: What's the best
way to encapsulate information and behavior when there is no state?

Thanks.
 
I

Intransition

Reading on the subject with regards to Java, I think what I am
considering, rather then a singleton class, is a static class. But
what does a "static class" really look like in Ruby?
 
D

David Masover

Reading on the subject with regards to Java, I think what I am
considering, rather then a singleton class, is a static class. But
what does a "static class" really look like in Ruby?

Like a singleton, or like a module with a bunch of "class methods".
 
R

Richard Conroy

[Note: parts of this message were removed to make it a legal post.]

So that's the idea. Getting back to the main question: What's the best
way to encapsulate information and behavior when there is no state?
There's a bit of a contradiction here. To paraphrase what you said:

What's the best
way to encapsulate "State" and behavior when there is no state?

If there is unique information captured in objects (encapsulation) you have
state.

You should look at modeling the system in a purely functional manner, but it
is hard
to see what you are attempting to do.
 
I

Intransition

There's a bit of a contradiction here. To paraphrase what you said:

What's the best
way to encapsulate "State" and behavior when there is no state?

If there is unique information captured in objects (encapsulation) you ha= ve
state.

Sorry, by "information" I just meant constants (static information).
You should look at modeling the system in a purely functional manner, but= it
is hard
to see what you are attempting to do.

Maybe it will help if I explain how I got to this question. I started
with a set of classes that all had one attribute, using a base class:

class UnitType
attr :power
# ... methods ...
end

I had:

class Meter < UnitType
# ... override methods ...
end

class Second < UnitType
# ... override methods ...
end

etc...

So each one was instantiated to track the power of a given unit. But
then I realized that it would be better to couple the type and power
via another class:

class Unit
def initialize(unit_type, power)
@unit_type =3D unit_type
@power =3D power
end
end

And remove the power attribute from the UnitType class. Thus I was
left with a bunch of classes that had no state.
 
R

Richard Conroy

[Note: parts of this message were removed to make it a legal post.]

Maybe it will help if I explain how I got to this question. I started
with a set of classes that all had one attribute, using a base class:

class UnitType
attr :power
# ... methods ...
end

I had:

class Meter < UnitType
# ... override methods ...
end

class Second < UnitType
# ... override methods ...
end

etc...

So each one was instantiated to track the power of a given unit. But
then I realized that it would be better to couple the type and power
via another class:

class Unit
def initialize(unit_type, power)
@unit_type = unit_type
@power = power
end
end

And remove the power attribute from the UnitType class. Thus I was
left with a bunch of classes that had no state.
Okay, this makes a bit more sense. This kind of unit
representation/conversion is a common idiom in DSL
tutorials. It is quite common to patch in unit specific methods into Fixnum
to represent these. Have a google
for it.

The last code example seems pretty sound in any case if you intend to make
unit_type specific classes,
though I can see now why you are leaning towards a singleton approach.
 
R

Robert Klemme

Sorry, by "information" I just meant constants (static information).


Maybe it will help if I explain how I got to this question. I started
with a set of classes that all had one attribute, using a base class:

class UnitType
attr :power
# ... methods ...
end

I had:

class Meter < UnitType
# ... override methods ...
end

class Second < UnitType
# ... override methods ...
end

etc...

So each one was instantiated to track the power of a given unit. But
then I realized that it would be better to couple the type and power
via another class:

class Unit
def initialize(unit_type, power)
@unit_type = unit_type
@power = power
end
end

And remove the power attribute from the UnitType class. Thus I was
left with a bunch of classes that had no state.

What's wrong with doing

class UnitType
class<<self
attr_accessor :power
end

# ... methods ...

def self.i_ve_got_the_power
puts "#{self}'s power is #{power}"
end
end

class Meter < UnitType
self.power = 123
# ... override methods ...
end

class Second < UnitType
self.power = 456
# ... override methods ...
end

irb(main):022:0> Meter.i_ve_got_the_power
Meter's power is 123
=> nil
irb(main):023:0* Second.i_ve_got_the_power
Second's power is 456
=> nil

?

Kind regards

robert
 
T

Tony Arcieri

[Note: parts of this message were removed to make it a legal post.]

What's wrong with doing

class UnitType
class<<self[...]
class Second < UnitType

This is the "Ruby-like" way to do it in my mind: using the singleton class
and inheritance. I have never found a valid reason to use singleton.rb and
don't really understand why it even exists. Ruby has first-class
singletons.
 
I

Intransition

What's wrong with doing

=A0 =A0class UnitType
=A0 =A0 =A0class<<self
=A0 =A0 =A0 =A0attr_accessor :power
=A0 =A0 =A0end

=A0 =A0 =A0# ... methods ...

=A0 =A0 =A0def self.i_ve_got_the_power
=A0 =A0 =A0 =A0puts "#{self}'s power is #{power}"
=A0 =A0 =A0end
=A0 =A0end

=A0 =A0class Meter < UnitType
=A0 =A0 =A0self.power =3D 123
=A0 =A0 =A0# ... override methods ...
=A0 =A0end

=A0 =A0class Second < UnitType
=A0 =A0 =A0self.power =3D 456
=A0 =A0 =A0# ... override methods ...
=A0 =A0end

irb(main):022:0> Meter.i_ve_got_the_power
Meter's power is 123
=3D> nil
irb(main):023:0* Second.i_ve_got_the_power
Second's power is 456
=3D> nil

Nothing. Indeed I think that is the way to do it (if the static-class
approach is taken). singleton.rb is again proven rather toothless.

thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top