Re: Using opDispatch as *magic* getter/setter. Possible or not?

2011-04-04 Thread Simen kjaeraas
On Thu, 31 Mar 2011 02:32:35 +0200, Aleksandar Ružičić  
ruzicic.aleksan...@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


Re: Using opDispatch as *magic* getter/setter. Possible or not?

2011-03-31 Thread Jacob Carlborg

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


Re: Using opDispatch as *magic* getter/setter. Possible or not?

2011-03-31 Thread Aleksandar Ružičić
On Thu, Mar 31, 2011 at 8:52 AM, Jacob Carlborg d...@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.s...@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...


Re: Using opDispatch as *magic* getter/setter. Possible or not?

2011-03-31 Thread Steven Schveighoffer

On Thu, 31 Mar 2011 02:52:15 -0400, Jacob Carlborg d...@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


Re: Using opDispatch as *magic* getter/setter. Possible or not?

2011-03-31 Thread Steven Schveighoffer

On Wed, 30 Mar 2011 21:50:43 -0400, spir denis.s...@gmail.com wrote:


On 03/31/2011 02:40 AM, Aleksandar Ružičić wrote:

2011/3/31 Aleksandar Ružičićruzicic.aleksan...@gmail.com:


Or maybe there is some other way to achive what I want and I'm not
aware of it? :-)



I know I could have used opIndex and opIndexAssign but I really want
config.section.entry syntax instead of config[section][entry]...


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?


In fact, opDot exists, but it is superseded by alias this (probably not  
exactly what you are looking for).


opDispatch is exactly what you want, and it should work, but you have to  
jump through the right hoops.


It also has some severe limitations and incorrect implementation (like  
many newer D features).


-Steve


Re: Using opDispatch as *magic* getter/setter. Possible or not?

2011-03-31 Thread Aleksandar Ružičić
On Thu, Mar 31, 2011 at 1:30 PM, Steven Schveighoffer
schvei...@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..


Re: Using opDispatch as *magic* getter/setter. Possible or not?

2011-03-31 Thread Steven Schveighoffer

On Thu, 31 Mar 2011 14:02:43 -0400, Kagamin s...@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


Re: Using opDispatch as *magic* getter/setter. Possible or not?

2011-03-30 Thread spir

On 03/31/2011 02:40 AM, Aleksandar Ružičić wrote:

2011/3/31 Aleksandar Ružičićruzicic.aleksan...@gmail.com:


Or maybe there is some other way to achive what I want and I'm not
aware of it? :-)



I know I could have used opIndex and opIndexAssign but I really want
config.section.entry syntax instead of config[section][entry]...


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).


denis
--
_
vita es estrany
spir.wikidot.com