Consider such code (this is just example not real code):
class Foo(url : String) extends Bar(url)
{
def say() { println(url) }
}
It compiles and it works. With nonsense results “of course”. I am too newbie to judge, but for me it serves no purpose but confusion — by definition it is impossible that the argument of the constructor could be reachable directly in another method.
Could someone more experience in Scala could point out condition when it might work or make sense? Or confirm my suspicion this is flaw in current Scala compiler.
Update
class Bar(val Url : String)
{
}
Why “nonsense”. Because my will (no “var” and no “val” in Foo) was to just pass the argument, nothing else. So when I actually use the constructor argument it is just matter of what entity I use by mistake. When you write on purpose, you hit the jackpot each time, but if you don’t (i.e. you make a mistake in spelling), you use entities by random. It is not the code does not make sense, it is the computation just does not make sense, I could roll a dice as well. There is a method scope, and I don’t see a reason why there shouldn’t be constructor scope.
Update — workaround
So it seems this evil construct is really part of the language (by design). As UserUnknown and Tomasz Nurkiewicz suggested the only line of defense against making stupid typo is convention, however lower-upper case is not good. “A” and “a” differ a lot, but “U” and “u” not much. Introducing one special character (as Tomasz showed) is much better, because it is possible to visually detect fishy usage of constructor argument.
I will use “$” for “just-passing” constructor arguments, it is harder to type for me, and you don’t see this character too often in the code.
Thank you for the answers!
Why it is evil? Because implicit actions should be allowed explicitly by users — good examples are “dynamic” in C#, implicit conversions in Scala. And examples of breaking this rule which led to tons of problems are — implicit conversions to bool in C++, implicit constructors in C++, declaration by usage in Perl. And this particular case is very, very close to the mentioned perlism, in Perl finally there was change in interpreter to detect such misusages, why Scala repeated the same mistake? I wonder.
It’s not a bug, it’s a feature. In fact, a really nice one. Need an example how useful it is? Here is how I use it with Spring and dependency injection via constructor:
Equivalent code in Java:
Still not convinced?
Short tutorial:
xwill become avariable with getters and setter.ywill become an immutable variable andzwill become an immutable variable only ifzzmethod is uncommented. Otherwise it will remain a constructor argument. Neat!UPDATE: I see your point now! The following code works as expected by accessing
urlvariable in base class:I agree, this is both ugly and is asking for trouble. In fact I once hit this problem myself when using Scala classes as Hibernate entities – I used constructor parameter instead of field in base class which caused duplicated field to be created: one in base class and one in derived class. I wouldn’t even notice but Hibernate was screaming at runtime that duplicated column mapping was defined.
So I have to somewhat agree with you – this is somehow confusing and might be error-prone. This is the price you pay for “implicitness” and concise code.
However note that no modified and
valmodifier before constructor argument are different. Without modified immutable field is created, whilevaladditionally adds getter.