subclassing

Jesse Phillips jessekphillips+D at gmail.com
Tue Nov 2 14:54:35 PDT 2010


spir Wrote:

> On Tue, 02 Nov 2010 12:33:16 -0400
> Jesse Phillips <jessekphillips+D at gmail.com> wrote:
> 
> > spir Wrote:
> > 
> > 
> > > * Why does D allow me redefining (data) slots in the subclass OddSquares, which exist in the superclass? (I did this first without noting, by copy & paste ;-)
> > 
> > This is either a bug or so that you don't have name clashes with all the super classes (could really reduce the available names).
> 
> I have name clashes, that's what I meant with "redefining". Test case:

No, a name clash would mean it complains that you already have a variable of the same name (i.e. the names clash).

I believe it is called shadowing, and it is actually common. Local/Class variables are able to shadow global variables. Local function variables can shadow class variables. As to whether this is best, I can't say. But I can say Java does it, and I don't think it is a common mistake:

http://ideone.com/0Ny9X

> > I am also not sure why you have alias T type. T is already an alias for the type, and you never use it so maybe it is just having fun testing out alias.
> 
> It for possible use in other app. Gives me access for the actual type from an instance, under instance.type. Found the trick in the book "The D P.L.".

Ah, yes. Though this is not needed with a Range. You can use std.range.ElementType to obtain the type returned from a range.

> I take the opportunity to ask whether there is a way for an element to access its own type, say x.type. I found typeid, but its only a string.

Yes, typeof(x);

> Also, is there any kind of Type type, with variables of it? (Similar to function variables.)

No, but you can look into TypeTuples and Tuples

http://digitalmars.com/d/2.0/phobos/std_typetuple.html
http://digitalmars.com/d/2.0/phobos/std_typecons.html

> Finally, can an element know its (variable) name? Or can we set it on itself, provided it's a struct or class instance with a dedicated field, for example by reading the scope? (This is an idiom in Python, but sure it's a dynamic language.)

No and Yes. You can turn a (something) name into a string with .stringof

string hello;

hello = hello.stringof;

But at this point what you are probably looking for is to use an alias template parameter for the function you are calling.

auto someFunction(alias mayVar)() {
...
}

> > I understand you are trying to discover the benefits through your own design,
> 
> Exactly! I find this whole feature really attractive, but complex and abstract. (In such cases, try-&-do-it-yourself is a learning method that works well with me, esp to understand the how's and why's.)

Yeah, sometimes I think I can do something better so I go to build it. When I finish and look back at what I'm replacing, I realize... I did it the same way.

> Great, thank you for the example. I don't understand the benefit of @property (which indeed does not seem to have the same meaning as in python.)

Currently none. As mentioned in read-only, @propery isn't really implement yet. The benefit is to be able to call/asign to functions as though they were field variables.

> I just don't want to force client code to initialize, since anyway the range is useless before init. With init in constructor, they get the range ready to use.
> > You will notice I acutally removed that call for the range above.
> > 
> > I guess you could say that the real complaint was due to the desire to time how long it took to load the data (build the ranges) and how long it took to do the filtering. That meant I was separating the initialization phase from the construction of the range itself. Any way you rarely see this creep into user code.
> 
> I do not really understand whether you mean it's better w/o init in constructor, and why.

Purely how I wanted to use my range. Otherwise you shouldn't force the use of popFront() before using the range. I probably would have built my program differently had I known I wanted the separation I did.

> > So the only other piece to inform you of (to help you learn D) is that find is found in std.algorithm and does exactly what you have demonstrated, with a slightly different call:
> > 
> > auto element = find!((int e){return (e>200 && e<250))(range);
> > 
> > or
> > 
> > auto element = find!("a>200 && a<250")(range);
> > 
> > And will return a range starting at the element found, however it will not stop when over 250. For that you use filter instead.
> > 
> > auto element = filter!("a>200 && a<250")(range);
>  
> I considered making find (and other funcs using ranges) return the range, as is described in the article. But as of now, the only advantage I could guess is chaining method calls.
> 
> [OT topic="style"]
> I don't use such patterns often because I prefere to clearly expose steps, for ease of reading, esp with carefully chosen names. eg in Python:
> 
> def listText1(elements, sep='', lDelim='',rDelim=''):
>     return "%s%s%s" %(lDelim , sep.join(str(e) for e in elements) , rDelim)
> 
> def listText2(elements, sep='', lDelim='',rDelim=''):
>     elementTexts = (str(e) for e in elements)
>     content = sep.join(elementTexts)
>     return "%s%s%s" %(lDelim , content , rDelim)
> 
> I'm sure a non-pythonist can easily read listText2, even with the strange expression on 1st line, less sure about listText1 :-)
> [/OT]

But your example is chaining calls, just storing each peace before passing it on. In D elements and elementTexts are Ranges. And maybe you want to sort your list (creates a sorted Range), then only join the elements that start at 'j'. Each of these is a step that can build on the other whether stored in a variable or not.



More information about the Digitalmars-d-learn mailing list