with statement not triggering opDispatch?
Meta via Digitalmars-d
digitalmars-d at puremagic.com
Thu Feb 5 12:46:55 PST 2015
On Thursday, 5 February 2015 at 20:45:36 UTC, Meta wrote:
> On Thursday, 5 February 2015 at 16:27:01 UTC, Alex Parrill
> wrote:
>> DMD does not seem to consider `opDispatch` when looking up
>> variables in a `with` block, or . Is this intentional, or a
>> bug/oversight?
>>
>> For example:
>>
>> import std.typecons;
>> import std.stdio;
>>
>> struct MyStruct {
>> auto opDispatch(string name)() {
>> return name~"!";
>> }
>> }
>>
>> void main() {
>> auto obj = MyStruct();
>> with(obj)
>> writeln(helloworld());
>> }
>>
>> Fails to run with the following error:
>>
>> $ rdmd test.d
>> test.d(14): Error: undefined identifier helloworld
>> Failed: ["dmd", "-v", "-o-", "test.d", "-I."]
>>
>> Even though `helloworld` should be "defined", by way of the
>> `opDispatch` template.
>>
>> This also occurs when looking up identifiers in methods, when
>> not prefixing the identifiers with `this`:
>>
>> import std.typecons;
>> import std.stdio;
>>
>> struct MyStruct {
>> auto opDispatch(string name)() {
>> return name~"!";
>> }
>>
>> void run() {
>> writeln(helloworld()); // Error: no identifier `helloworld`
>> }
>> }
>>
>> void main() {
>> auto obj = MyStruct();
>> obj.run();
>> }
>>
>> I can work around it via introducing a wrapper struct that
>> contains the wrapped struct and uses `alias this` on it, which
>> fixes the identifier resolution with methods, but not with
>> `with`:
>>
>> import std.typecons;
>> import std.stdio;
>>
>> struct MyStruct {
>> auto opDispatch(string name)() {
>> return name~"!";
>> }
>> }
>>
>> struct MyStructWrapper {
>> MyStruct __mystruct;
>> alias __mystruct this;
>>
>> void run() {
>> writeln(helloworld()); // Prints "helloworld!"
>> }
>> }
>>
>> void main() {
>> auto obj = MyStructWrapper();
>> obj.run();
>> with(obj) writeln(helloworld()); // Still fails
>> }
>>
>> My use case for this is a D implementation of Mustache that
>> compiles templates at compile-time, and can be used with
>> arbitrary objects. The structure maintains the context stack
>> (stored as a tuple), with `opDispatch` forwarding accesses to
>> the first object in the stack that contains the named
>> identifier. The tag content would be retrieved like
>> `with(context) return mixin(tag_content);`, so that
>> `{{helloworld}}` would generate `with(context) return
>> helloworld;`.
>
> This is probably an oversight as nobody's thought to use
> opDispatch and with in that manner. I don't know what the
> consensus will be on if it's a bug or not, but you can file an
> issue at issues.slang.org
That should be issues.dlang.org. I hate smartphones and their
autocorrect...
More information about the Digitalmars-d
mailing list