with statement not triggering opDispatch?

Meta via Digitalmars-d digitalmars-d at puremagic.com
Thu Feb 5 12:45:34 PST 2015


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


More information about the Digitalmars-d mailing list