Created
December 21, 2010 15:44
-
-
Save aboisvert/750082 to your computer and use it in GitHub Desktop.
When do we get first-class properties in Scala???
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Employee(var employer: Employer) | |
class Employer(var name: String) | |
object Test { | |
import Properties._ | |
// killer boilerplate of death !!! | |
val name1 = property( | |
(e: Employee) => e.employer.name, | |
(e: Employee, name: String) => e.employer.name = name | |
) | |
val someEmployer = new Employer(name = "foo") | |
val someEmployee = new Employee(employer = someEmployer) | |
name1.set(someEmployee, "bar") | |
name1.get(someEmployee) // => "bar" | |
val name0 = name1 using someEmployee | |
name0.set("baz") | |
name0.get // => "baz" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait ReadableProperty0[R] extends Function0[R] { | |
override def apply() = get() | |
def get(): R | |
} | |
trait WritableProperty0[R] { | |
def set(r: R): Unit | |
} | |
trait RWProperty0[R] extends ReadableProperty0[R] with WritableProperty0[R] | |
trait ReadableProperty1[T1, R] extends Function1[T1, R] { | |
override def apply(t1: T1) = get(t1) | |
def get(t1: T1): R | |
def using(t1: T1) = new ReadableProperty0[R] { | |
override def get() = ReadableProperty1.this.get(t1) | |
} | |
} | |
trait WritableProperty1[T1, R] { | |
def update(t1: T1, r: R) = set(t1, r) | |
def set(t1: T1, r: R): Unit | |
def using(t1: T1) = new WritableProperty0[R] { | |
override def set(r: R) = WritableProperty1.this.set(t1, r) | |
} | |
} | |
trait RWProperty1[T1, R] extends ReadableProperty1[T1, R] with WritableProperty1[T1, R] { | |
override def using(t1: T1): ReadableProperty0[R] with WritableProperty0[R] = new RWProperty0[R] { | |
override def get() = RWProperty1.this.get(t1) | |
override def set(r: R) = RWProperty1.this.set(t1, r) | |
} | |
} | |
object Properties { | |
def property[T1, R](read: => (T1 => R), write: (T1, R) => Unit) = new RWProperty1[T1, R] { | |
override def get(t1: T1) = read(t1) | |
override def set(t1: T1, r: R) { write(t1, r) } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment