"Matthias Georgi" <matti_g / gmx.de> schrieb im Newsbeitrag
news:opr7zo17147zr67k / mail.gmx.net...
> On Fri, 14 May 2004 18:08:57 +0900, Robert Klemme <bob.news / gmx.net>
wrote:
>
> > 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