| Thread overview | ||||||
|---|---|---|---|---|---|---|
|
February 05, 2015 with statement not triggering opDispatch? | ||||
|---|---|---|---|---|
| ||||
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;`.
| ||||
February 05, 2015 Re: with statement not triggering opDispatch? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alex Parrill | 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
| |||
February 05, 2015 Re: with statement not triggering opDispatch? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Meta | 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...
| |||
February 06, 2015 Re: with statement not triggering opDispatch? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Meta | On Thursday, 5 February 2015 at 20:45:36 UTC, Meta wrote: > > 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 Looks like two issues have already been opened: https://issues.dlang.org/show_bug.cgi?id=6400 and https://issues.dlang.org/show_bug.cgi?id=9808. Looks like neither have any discussion or resolution, which is a bit disheartening. I'll see if I can bump the latest one. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply