“Matthias Georgi” matti_g@gmx.de schrieb im Newsbeitrag
news:opr7zo17147zr67k@mail.gmx.net…
This is debatable - and there have been lengthy debates about that.
For
example, Java’s class String is declared ‘final’, i.e. it can’t be
inherited from. I have only a slight tendency to not do it but I
agree
that there might be situations where subclassing is the more
appropriate
option. Though it seems to me that they are rather rare than common.
e.g. a class which represents the an object id, the object id have to be
a string , because it’s stored in database.
It has to be convertable to a string, but that does not mean OID isA
String.
So to get a part of the id,
you define an accessor, which scans the string.
… and by using String methods I can easily break the OID:
class OID < String
RX = /^(\d+)-(\d+)$/
def initialize(str)
raise ArgumentError unless RX =~ str
super
end
def major; RX =~ self; $1; end
def minor; RX =~ self; $2; end
end
oid = OID.new(“123456”) # wrong format => error, ok!
oid = OID.new(“123-456”)
oid.gsub!(/.*/, ‘X’)
oid.major # oops!
I’d say an OID is not a string. It has a String representation, but it is
conceptually something completely different. Especially if your OIDs must
conform to a certain format as shown above. Also, you might want to
change the internal representation if that is more appropriate at some
point in time (e.g. because performance of #major and #minor is too bad).
But from a practical view, I’d rather go with some module_functions,
because the conversions all over the code like String#to_oid are too
messy.
Note also, that with Delegator you can quite easily wrap a String and
add
functionality as you see fit.
Yes, but when it comes to binary representation, I have to call
everywhere
to_s, also not beatyful.
but the easiest way is to extend class String.
namespaces would be really good solution for that.
How exactly would namespaces solve this problem?
The term namespace is possibly wrong, but my idea is:
namespace MyNames
class String # makes a copy of String class
end
s = “xxx” # constructor of MyNames::String is called
end
Same thing for every string creation.
But that would require a lot of change in the interpreter,
every rb_str_new() must know the current namespace.
That’s not how namespaces work (at least in C++). First, class String in
MyNames is a totally new String class that has nothing to do with any
other class with the same name unless you inherit that class. Second,
“xxx” is a literal that is bound to the standard type String (char* in
C/C++), similarly as 1.234 is bound to represent a float. You don’t
change that by introducing namespaces. Third, places in code that create
strings one way or the other will always create standard strings. If the
declaration of a new class with the same name as another class in a
different namespace had the side effect that all places in code now use
the new class, type safety would be completely down the drain - apart from
all other sorts of problems (how should a compiler handle this in C++?).
What you’d rather want is a mechanism that replaces the binding of certain
literals to types (“xxx” => String, 1.234 => float etc.). But then, in
Ruby it’s far easier to simply extend String. Still I think in most cases
it is not a good idea to use a sub class of String as an application
class, since that brings all sorts of problems with it.
Recently I attended a lecture of the creator(Erik Ernst) of the
language gbeta, which solves this problem nicely, but
from a very different approach.
How do they do it there?
robert
···
On Fri, 14 May 2004 18:08:57 +0900, Robert Klemme bob.news@gmx.net wrote: