4

Is there scala equivalent of python __getattr__ / __setattr__ (and other __*__ methods?). Some thing built-in or maybe some traits?

4
  • i don't really know python but do you mean things like getOrElse methods or Scala's Option objects? Both help prevent null pointer exceptions, if that's what you are looking for Commented May 18, 2012 at 20:03
  • __*attr__() are used to control behavior when accessing an object's attributes. Commented May 18, 2012 at 21:08
  • Can you be more specific about what you want to do? This is way too broad. Commented May 18, 2012 at 21:17
  • @dhg to add & control "fields" dynamically at runtime Commented May 20, 2012 at 11:49

2 Answers 2

11

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:

Global things

  • __call__apply() // pretty much identical in behaviour
  • __metaclass__ // use case dependent:
    • currently class inheritance or trait mixins may be useful
    • in many cases all that metaclass does is instance construction which avoids a call to super(); 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 = ...

Container Types

  • __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.

Operators

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), …

Context manager

  • __enter__, __exit__ // in most cases, a function argument fulfills the same purpose

See also: List of Scala's "magic" functions

Sign up to request clarification or add additional context in comments.

1 Comment

(Is there something wrong apart from the fact that __getattr__ and __setattr__ are prominently missing?)
2

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

1 Comment

__getattr__ and __setattr__ are not directly related to the uniform access principle in Python (at least not since the property decorator has been established).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.