Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
March 31, 2011 Using opDispatch as *magic* getter/setter. Possible or not? | ||||
---|---|---|---|---|
| ||||
Is it possible to use opDispatch as generic getter and setter at the same time? Something like __get() and __set() in PHP.. this is what I've tried: https://gist.github.com/895571 and I get Error: template instance opDispatch!("bar") matches more than one template declaration, path\to\test.d(57):opDispatch(string entryName) and path\to\test.d(66):opDispatch(string entryName) Is mixing @property with opDispatch supposed to work at all or is opDispatch only ment for method calls? Or maybe there is some other way to achive what I want and I'm not aware of it? :-) |
March 31, 2011 Re: Using opDispatch as *magic* getter/setter. Possible or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aleksandar Ružičić | On 3/31/11 2:32 AM, Aleksandar Ružičić wrote: > Is it possible to use opDispatch as generic getter and setter at the > same time? Something like __get() and __set() in PHP.. > > this is what I've tried: https://gist.github.com/895571 > > and I get Error: template instance opDispatch!("bar") matches more > than one template declaration, path\to\test.d(57):opDispatch(string > entryName) and path\to\test.d(66):opDispatch(string entryName) > > Is mixing @property with opDispatch supposed to work at all or is > opDispatch only ment for method calls? > > Or maybe there is some other way to achive what I want and I'm not > aware of it? :-) You can't have two methods named opDispatch like that. You can do something like this: class Foo { @property ref ConfigSection opDispatch(string sectionName, Args ...)(Args args) { static if (Args.length == 0) {} // getter else static if (Args.length == 1) { auto value = args[0]; } // setter } Or, I think this will work as well: @property ref ConfigSection opDispatch(string sectionName, Args ...)(Args args) if (Args.length == 0) { // getter } @property ref ConfigSection opDispatch(string sectionName, Args ...)(Args args) if (Args.length == 1) { // setter } } auto foo = new Foo; foo.bar; // works foo.bar = 3; // currently does not work, bug foo.bar(3); // works -- /Jacob Carlborg |
March 31, 2011 Re: Using opDispatch as *magic* getter/setter. Possible or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Thu, Mar 31, 2011 at 8:52 AM, Jacob Carlborg <doob@me.com> wrote: > > Or, I think this will work as well: > > @property ref ConfigSection opDispatch(string sectionName, Args ...)(Args > args) if (Args.length == 0) > { > // getter > } > > > @property ref ConfigSection opDispatch(string sectionName, Args ...)(Args > args) if (Args.length == 1) > { > // setter > } > } > > auto foo = new Foo; > > foo.bar; // works > foo.bar = 3; // currently does not work, bug > foo.bar(3); // works > > -- > /Jacob Carlborg > That's great! Thanks! If just the assignment worked thought, it would be perfect.. Btw, do you know which issue # that is? I'd like to read more about that bug but can't find it on bugzilla. On Thu, Mar 31, 2011 at 3:50 AM, spir <denis.spir@gmail.com> wrote: > > Agreed. And I would really have an answer to your question, since I tried to > do the same thing. Don't understand why D does not have an 'opMember' or > 'opDot'. Someone knows? > This would be one of the first metamethods I would introduce in a language > (definitely before operator overloading). > Yeah, opMember would be great, but it seems that we'll be able to use opDispatch for that in a way Jacob described once the bugs are ironed out.. But until then I'll have to live with "ugly" indexing sytnax... |
March 31, 2011 Re: Using opDispatch as *magic* getter/setter. Possible or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Thu, 31 Mar 2011 02:52:15 -0400, Jacob Carlborg <doob@me.com> wrote: > On 3/31/11 2:32 AM, Aleksandar Ružičić wrote: >> Is it possible to use opDispatch as generic getter and setter at the >> same time? Something like __get() and __set() in PHP.. >> >> this is what I've tried: https://gist.github.com/895571 >> >> and I get Error: template instance opDispatch!("bar") matches more >> than one template declaration, path\to\test.d(57):opDispatch(string >> entryName) and path\to\test.d(66):opDispatch(string entryName) >> >> Is mixing @property with opDispatch supposed to work at all or is >> opDispatch only ment for method calls? >> >> Or maybe there is some other way to achive what I want and I'm not >> aware of it? :-) > > You can't have two methods named opDispatch like that. You can do something like this: > > class Foo { > > @property ref ConfigSection opDispatch(string sectionName, Args ...)(Args args) > { > static if (Args.length == 0) {} // getter > else static if (Args.length == 1) { auto value = args[0]; } // setter > } The issue is that you can't have two templates with the same exact template parameters, even if they have different function parameters. This is because the compiler first instantiates the template, then calls the function. I hope this restriction can be lifted for the special case of template functions. The ability to overload template functions is long overdue, especially when you are overloading with normal functions. > Or, I think this will work as well: > > @property ref ConfigSection opDispatch(string sectionName, Args ...)(Args args) if (Args.length == 0) > { > // getter > } > > > @property ref ConfigSection opDispatch(string sectionName, Args ...)(Args args) if (Args.length == 1) > { > // setter > } > } or you can change the template parameters in the opDispatch setter: @property ref ConfigSection opDispatch(string sectionName, T : string)(T arg) -Steve |
March 31, 2011 Re: Using opDispatch as *magic* getter/setter. Possible or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thu, Mar 31, 2011 at 1:30 PM, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>
> or you can change the template parameters in the opDispatch setter:
>
> @property ref ConfigSection opDispatch(string sectionName, T : string)(T
> arg)
>
> -Steve
>
Thanks, that's much more readable I now have these templates:
// getter
@property ref ConfigEntry opDispatch(string entryName)() pure {
if (!(entryName in entries)) {
entries[entryName] = new ConfigEntry(config);
}
return entries[entryName];
}
// setter
@property void opDispatch(string entryName, T : string)(in T value) {
if (!(entryName in entries)) {
entries[entryName] = new ConfigEntry(config);
}
entries[entryName] = value;
}
And that compiles just fine (I dunno if it runs ok since I'm currently on windows and I've been messing with my setup so optlink can't stop complaining.. sigh..)
but due to bug not allowing foo.bar = "abc"; I've also added opIndex and opIndexAssign (apparently you cannot only have opIndexAssign defined) as temporary "backup" solution..
|
March 31, 2011 Re: Using opDispatch as *magic* getter/setter. Possible or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer Wrote:
> The issue is that you can't have two templates with the same exact template parameters, even if they have different function parameters. This is because the compiler first instantiates the template, then calls the function.
If two template instances have the same exact template parameters, it's one instance, isn't it? There's no need to instantiate it twice.
|
March 31, 2011 Re: Using opDispatch as *magic* getter/setter. Possible or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Thu, 31 Mar 2011 14:02:43 -0400, Kagamin <spam@here.lot> wrote:
> Steven Schveighoffer Wrote:
>
>> The issue is that you can't have two templates with the same exact
>> template parameters, even if they have different function parameters.
>> This is because the compiler first instantiates the template, then calls
>> the function.
>
> If two template instances have the same exact template parameters, it's one instance, isn't it? There's no need to instantiate it twice.
Yes, but we allow function overloading. Problem is, you can't do *template* function overloading unless you do it on the template parameters.
For instance, these two cannot be instantiated:
void foo(string s)(int x) {writeln(x);}
void foo(string s)(string y) {writeln(y);}
because the compiler considers that you defined the same template twice with different implementations.
However, if you do:
void foo(string s, T)(T x) if (is(T == int)) { writeln(x); }
void foo(string s, T)(T x) if (is(T == string)) { writeln(x); }
then you have two different templates, and the compiler has no issue.
This is a huge nuisance for operator overloading and opDispatch because the only required template parameter is the string of the operator/function name.
I suspect that fixing this will be a large change in the compiler.
-Steve
|
April 05, 2011 Re: Using opDispatch as *magic* getter/setter. Possible or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aleksandar Ružičić | On Thu, 31 Mar 2011 02:32:35 +0200, Aleksandar Ružičić <ruzicic.aleksandar@gmail.com> wrote: > Is it possible to use opDispatch as generic getter and setter at the > same time? Something like __get() and __set() in PHP.. > > this is what I've tried: https://gist.github.com/895571 > > and I get Error: template instance opDispatch!("bar") matches more > than one template declaration, path\to\test.d(57):opDispatch(string > entryName) and path\to\test.d(66):opDispatch(string entryName) > > Is mixing @property with opDispatch supposed to work at all or is > opDispatch only ment for method calls? > > Or maybe there is some other way to achive what I want and I'm not > aware of it? :-) Bug 620[1] is related to what you ask. I have written a solution there, but I do not remember how well it works, and have no way of testing it currently: template opDispatch( string name ) { auto opDispatch( T... )( T args ) { // Do something! } } [1]: http://d.puremagic.com/issues/show_bug.cgi?id=620 -- Simen |
April 05, 2011 Re: Using opDispatch as *magic* getter/setter. Possible or not? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | On Tue, Apr 5, 2011 at 6:46 AM, Simen kjaeraas <simen.kjaras@gmail.com> wrote:
> Bug 620[1] is related to what you ask. I have written a solution there, but I do not remember how well it works, and have no way of testing it currently:
>
> template opDispatch( string name ) {
> auto opDispatch( T... )( T args ) {
> // Do something!
> }
> }
>
> [1]: http://d.puremagic.com/issues/show_bug.cgi?id=620
>
> --
> Simen
>
Thank you, I will try your workaround.
|
Copyright © 1999-2021 by the D Language Foundation