Chad J wrote:
John C wrote:

2) Indexing:

  struct Map(K, V) {

    void opIndexAssign(V value, K key) { ... }
    V opIndex(K key) { ... }

  }

  class WebClient {

    private Map!(string, string) headers_;

    Map!(string, string) headers() {
      return headers_;
    }

  }

  auto client = new WebClient();
  client.headers["User-Agent"] = "MyWebClient";

The compiler says client.headers() is not an lvalue (adding 'ref' in D2
changes nothing).

This is nearly the same thing as the "a.b.c = 3;" example given in the
"a.b.c = 3;" thread.  The .b is your .headers.  It's slightly more
forgiving though, since you are calling a function on the returned
struct and not accessing a field.  The setter never needs to be called
in your example.

I'll use the compiler's rewritting technique to show you what it looks like:

client.headers["User-Agent"] = "MyWebClient";
client.headers.opIndexAssign("User-Agent","MyWebClient");
client.headers().opIndexAssign("User-Agent","MyWebClient");

client.headers() creates a /new/ Map!(...) struct, so the opIndexAssign
will not be called on the one you want it to be called on.

Adding 'ref' should change that.  That sounds like a bug.

In this specific example, property syntax is not truly necessary.  That
ref returns were added should make this doable.

It actually works if the "ref" is attached not to the WebClient.headers property, but to the Map.opIndex operator (and opIndexAssign is removed, or course).

Reply via email to