On 01/10/2015 11:20 AM, Jacob Carlborg wrote:
On 2015-01-10 07:46, DaveG wrote:
I might be crazy, but it seems like the compiler has all the information
necessary to figure this out and it would make user code simpler, less
error prone, and more efficient. So does anybody have any idea on how to
actually achieve this?
I'm not exactly sure if this is what you want but you can implement the
"opDispatch" [1] method in a class or struct. This method will be called
if no other method exists with the same name. There's also something
called "alias this" [2] that allows you to do something similar.
class Foo
{
void foo () {}
void opDispatch (string name)() {}
}
auto f = new Foo;
f.foo(); // will call "foo"
f.bar(); // will be lowered to f.opDispatch!("bar")();
If you're implementing an ORM I would recommend executing queries
lazily. You can do something like this:
class Person : ORM.Base
{
String name;
Int age;
// this method returns a range/proxy that implements the range api [3]
static ORM.Range!(Person) all () {}
}
"String" would look something like this:
struct String
{
alias get this;
// this method will fetch the data from the database
private string get ();
}
Using the interface would look something like this:
auto p = Person.all(); // no database query has been performed yet
// the range interface makes it possible to use a foreach
// when starting the foreach loop is when the first query will happen
foreach (e ; p)
{
// this call will trigger a call to the "get" method in "String"
// via the "alias this"
string name = e.name;
writeln(name);
}
The idea isn't bad, but the performance will suck. This is generally
known as N+1 query, only that this is even worse, as each field is
queried individually.
Here is a sketch for an optimal solution. I'm actually eagerly waiting
that someone finally implements it.
http://dpaste.dzfl.pl/cd375ac594cf