I'll try and answer all the points in one mail :)
The source is here:
http://github.com/scala-incubator/autoproxy-plugin
And the wiki here:
http://wiki.github.com/scala-incubator/autoproxy-plugin
The tabs at the top of the page should help you...
I did also consider @forward in addition to @with, @delegate and
@proxy
The same logic applies as for delgate, I wanted a verb instead of a
noun
(so it would have to be @forwardto - no so pretty)
Plus I wanted to keep it nice and short. :)
My thinking is that "the delegates forward to the object that is
proxied", the the actual delegates (or forwarders) are the synthesised
methods and not the target object.
Also a few notes on where Scala differs from vanilla Java, things make
a bit more sense knowing this:
- all vals (immutable references) are by default made public final
(though you can override the public if you wish)
- vals and vars are actually implemented as a private field, plus
accessor methods
So:
var x = "Hello World"
becomes (in equivalent java)
private String x = "hello World!";
String x() { return x; }
String x_=(String x$ ) { x = x$; }
This isn't quite accurate, as the generatted getter doesn't require
parens to call, and '=' isn't valid in a Java method name (it's
actually encoded as "$equals"), but it does illustrate the principle.
Surprisingly, '$' is valid in an identifier, but strongly discouraged
in handwritten code because it risks clashing with generated stuff.
Also, member variables and methods occupy the same namespace in scala.
- classes have one primary constructor, other constructors can be
written but must delegate to the primary
This means that you have a guaranteed construction path for variables
that simply must be created,
there's no way to sidestep by having a second constructor - this helps
avoids a few nasty problems
The primary constructor is all the code between the opening and
closing braces of the class definition, except for method
definitions. Variables (typically) declared here get lifted to the
status of class members.
- if you need to pass 'this' to the object that you're forwarding to,
scala can help with lazy vals
i.e.
class Foo {
@proxy lazy val bar = new Bar(this)
//bar is initialised when first accessed
}
- traits...
A Scala trait is internally generated as both a class and an
interface.
This means that if Bar is a trait then it's also an interface, and
that interface can also be synthetically added to Foo's superclasses.
[in more depth: The class contains just static methods that all take
an additional 'self' argument, so they know the instance they're
operating on. Instances of the trait (usually some other class plus a
mixin) then have generated methods that forward to the static
implementations - this allows for compound types such as "Cube with
Colour" where all methods from the Colour interface are implemented in
"Cube with Colour" as forwarders.]