Is there scala equivalent of python __getattr__ / __setattr__
(and other __*__
methods?). Some thing built-in or maybe some traits?
For __getattr__
and __setattr__
you’ll have to wait until someone with more insight describes the new Scala 2.10 reflection API. (And of course: it won’t be directly translatable ever. It depends completely on your use case. If you just want a dynamic class, there will be a Dynamic
trait in the future; if you just want a tiny bit of that, then designing around pattern matching may be an obvious choice.)
As for the multitude of other __*__
methods in Python:
__call__
→ apply()
// pretty much identical in behaviour__metaclass__
// use case dependent:
class
inheritance or trait
mixins may be usefulsuper()
; in Scala super()
is always called in the constructor.__repr__
, __str__
→ toString()
__eq__
→ equals()
__init__
// implicitly called in the class body__new__
// not directly existent; depending on use case early initialisation __del__
// missing
__nonzero__
// not really, except implicit def toBool[MyType](a: MyType): Boolean = ...
__len__
⇝ length
, size
or whatever is the convention in the container__getitem__
→ apply(i: IndexType)
// containers are functions in Scala__setitem__
→ update(i: IndexType, v: ValueType)
__delitem__
// no special handling needed; container convention__iter__
→ foreach(block: ValueType => Unit)
// with return value: map
, flatMap
Notably, apply
and update
are special in Scala, just as their Python counterparts. They allow for the following Syntax:
val x = collection(elem) // val x = collection.apply(elem)
collection(elem) = y // collection.update(elem, y)
Similarly, just as Python’s __iter__
allows a syntax like (el for el in container)
foreach
and map
make it possible to say for (el <- container) yield el
.
generally no special handling needed as we are allowed to define those directly:
__add__
, __sub__
, … // just define def + (arg: T)
or def - (arg: T)
this also includes comparison operators
__lt__
, __ge__
→ def <(other: T)
, def <=(other: T)
however, just as in Python, there are some special cases in the compiler for advanced things:
__radd__
, __rsub__
, … // right-associative operators; approx. def +: (arg: T)
or def -: (arg: T)
(append a :
)__iadd__
, __isub__
, … // modifying operators: def += (arg: T)
, …__enter__
, __exit__
// in most cases, a function argument fulfills the same purposeSee also: List of Scala's "magic" functions
I'm not sure what's the point here. Scala's uniform access principle means "fields" and methods share the same interface -- because, in fact, "fields" in Scala are getters and setters.
In other words, you can replace them like this:
var x: Int = 0
private[this] var _x = 0
def x = _x
def x_=(n: Int) { _x = n }
The getter and setter methods will control access to the private field you declared.
Now, if all you want is a way to provide non-static fields, you have to look at the Dynamic trait. It's experimental up to 2.9.2, but it will be available on 2.10, though behind a flag to warn people that this feature is dangerous (because it introduces dynamic typing, but if you don't think dynamic typing is dangerous, you should be fine).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With