Static opCall Factory Method Doesn't Work for Inner Classes

eris jvburnes at gmail.com
Tue Jan 12 10:09:50 PST 2010


Simen kjaeraas Wrote:

> eris <jvburnes at gmail.com> wrote:
> 
> > Every syntax combination in D to express a static opcall on an inner  
> > class doesn't work.  Both 'ldc' and 'gdc' generate compiler errors that  
> > say that 'this' is not available for static opCalls.  When I take the  
> > 'static' keyword off the opCall declaration the compiler error becomes  
> > something like: 'this' is required to access the opCall method.
> 
> Does the inbox need a pointer to the kernel class? If so, you're ferked.
> Well, not really, but then you have to explicitly pass it to opCall.
> See, to get this to work, you do this:
> 
> class foo {
>    static class bar { // static inner classes have no 'outer' pointer
>      static bar opCall( ) {
>        return new bar( );
>      }
>    }
> }
> 
> Hope this helps.
> 
> -- 
> Simen

Thanks, Simen.  I'll take a look at my code.  This whole effort is the result of a "single responsibility" refactoring where the kernel has responsibility for inbox and outbox creation since they implement kernel functionality.  The user space programs really only have an interface into these objects, such as...

interface Inbox(T) {
      T read();
      bool isEmpty();
..
}

interface Outbox(T) {
     void send(T msg);
..
}

class Kernel {
       ...
       // kernel inbox functionality including blocking read on empty
       class MsgBox(T) : Inbox!(T) {
           static MsgBox(T) opCall(T)(char[] name) {
                return new MsgBox!(T)(name);
           }
           T read() {
              if (isEmpty()) Fiber.yield;
              else return ...
           }
          ...
}

auto my_inbox = kernel.MsgBox!(String)("stdin");

Or at least that is what I was trying to achieve -- an interface into the kernel, literally.

This way the kernel maps the internal MsgBox object to an interface for the userland program to use.  Userland just sees my_inbox.read and not the implementation and doesn't care about kernel blocking.

I'm going to do another round of my refactoring and see if the problem doesn't resolve itself.

Perhaps the kernel should use external classes for the factories that aren't normally available to user-space programs.   Or maybe I'm making it too hard.  If userland wants it's own inbox, fine, but the kernel won't recognize it unless it has been registered with it.  I think part of the issue is that message sending and receiving between mailbox methods contain blocking functions if an outbox is full or an inbox is empty.  Those blocking functions are actually implemented by kernel primitives.  That's why userland needs an interface into them, but the actual mailbox methods need to be running in the kernel.

If that makes *any* sense.  :-)

(the problem may be that the program I'm working on so relatively large and I accidentally started working on one of the intermediate refactors)

eris




More information about the Digitalmars-d-learn mailing list