Thread overview
Assocative array lookup for object
Apr 12, 2023
Chris Katko
Apr 12, 2023
Salih Dincer
Apr 12, 2023
Salih Dincer
Apr 12, 2023
Ali Çehreli
Apr 12, 2023
Salih Dincer
April 12, 2023
class bitmapHandler
{
bitmap*[string] bmps;

void get(string name){return bmps[name]; /* plus other code */}
}

void usage()
{
bitmapHandler bh;
bitmap foo = bh.get("bar");  // works
bitmap foo2 = bh["bar"]; // desired
}

Should I be using opEquals? Or something different? The problem with 'alias this' here is I want to wrap access to the insides with getter functions that do various things like logging and error checking.

I mean, if I ruined some encapsulation, I could make a function called "bh" and have the usage:

bh("bar");

and have it access a singleton object.

April 12, 2023
You want the operator overload opIndex inside your class.

https://dlang.org/spec/operatoroverloading.html#array
April 12, 2023

On Wednesday, 12 April 2023 at 01:16:17 UTC, Chris Katko wrote:

>

Should I be using opEquals? Or something different? The problem with 'alias this' here is I want to wrap access to the insides with getter functions that do various things like logging and error checking.

I think you want to do an encapsulation like below.

class Handler(T)
{
  T*[string] data;

  auto set(string key, ref T value)
    => data[key] = &value;

  auto opIndex(string key)
    => *(key in data);
}

void main()
{
  class Bitmap {}
  Bitmap foo;

  auto handler = new Handler!Bitmap;
  handler.set("D Lang", foo);

  assert(handler["D Lang"] == &foo);
}

SDB@79

April 12, 2023

On Wednesday, 12 April 2023 at 04:57:58 UTC, Salih Dincer wrote:

>

I think you want to do an encapsulation like below.

  auto opIndex(string key)
    => *(key in data);

I made a little mistake and I'll fix it before someone rub nose in it :)

  auto opIndex(string key) {
    if(auto ret = key in data)
    {
      return *ret;
    }
    return null;
  }

  assert(handler["D Lang"] == &foo);
  assert(handler["null"] is null);

SDB@79

April 12, 2023
On 4/12/23 04:35, Salih Dincer wrote:

> I made a little mistake and I'll fix it before someone rub nose in it :)

You asked for it! :)

>    auto opIndex(string key) {
>      if(auto ret = key in data)
>      {
>        return *ret;
>      }
>      return null;
>    }

Not every type is null'able but nullable. ;) So, a design may use the following:

  https://dlang.org/library/std/typecons/nullable.html

Ali

April 12, 2023

On Wednesday, 12 April 2023 at 13:09:07 UTC, Ali Çehreli wrote:

>

Not every type is null'able but nullable. ;) So, a design may use the following:
https://dlang.org/library/std/typecons/nullable.html

I implemented Handler into the Voldermort build, which Walter loved so much. For convenience, I put an alias between the template and the function. But Nullable didn't work, instead it's returning T.init...

template Handler(alias A)
{
  alias T = typeof(A);

  auto Handler()
  {
    struct Impl
    {
      T*[string] data;

      void set(string key, ref T value)
      {
        data[key] = &value;
      }

      auto opIndex(string key)
      {
        if (auto ret = key in data)
        {
          return **ret;
        }
        return T.init;/*
        import std.typecons : Nullable;
        return Nullable!T.init;//*/
      }

      auto opSlice()
      {
        T[] result;
        foreach (ref value; data.values)
          result ~= *value;
        return result;
      }
    }
    return Impl();
  }
}

import std.stdio;

void main()
{
  struct List { string product; float price; }

  auto fruits = [ List("Manderin", 3.79),
                  List("Orange", 2.99),
                  List("Kiwi", 0.59),
  ];

  auto handlers = Handler!fruits;
  handlers.set("fruits", fruits);
  // please try it:  ^------v
  foreach(h; handlers["fruit"])
  {
    h.product.write(": ");
    h.price.writeln(" €");
  }

  auto handler = Handler!(List());

  import std.conv : text;
  foreach(i, ref fruit; fruits)
  {
    handler.set(i.text, fruit);
  }
  handler[].writeln;
} /* Prints:

  Manderin: 3.79 €
  Orange: 2.99 €
  Kiwi: 0.59 €
  [List("Kiwi", 0.59), List("Manderin", 3.79), List("Orange", 2.99)]

*/

SDB@79