Different field instances in class and parent/Call super constructor with method - scala

I am trying to call the super constructor from a class using a method. The whole setup looks like this:
class Straight(hand: Hand) extends Combination(Straight.makeHandAceLowIfNeeded(hand), 5)
object Straight {
private def makeHandAceLowIfNeeded(hand: Hand): Hand = {
...
}
}
While this does compile, it has some rather odd runtime behaviour. While debugging, I noticed that the Straight instances have the "hand" property defined twice. Can somebody tell me what is going on, and what the proper way is to call the super constructor with different arguments?
In my use case, I want to call the super constructor with a modified hand in which I replaced a card compared to the original constructor argument.
Debugger screenshot with duplicate field:
.

It's a perfectly fine way to call the superclass constructor. These are two private fields and they don't conflict, though you can rename one of them to avoid confusion during debugging (or if you want to access the superclass' value from the subclass). However, the field should only be generated for a class parameter if it's used outside a constructor, and in your case it doesn't appear to be. Did you simplify the definition of Straight?

Related

How to get a value from a field inside an nested class?

I'm trying to get a value of a field from inside a nested class in Kotlin, however, I'm having some difficulties with the logic. Somewhere I saw that it is possible through an interface, but I don't know where to start.
A simple sample:
class ExternalClass {
class InternalClass {
val internalValue = 2
}
val externalValue = InternalClass().internalValue
}
fun main(args: Array<String>) {
print(ExternalClass().externalValue)
}
The easiest way (and most obvious) to achieve this would be to instantiate the InternalClass class inside the External, however, in some cases, it would be necessary to pass several parameters in the Internal's constructor, which would not be the case.
So how would it be possible to do this through an interface?
Any idea or insight will be welcome!
Thank you!
Taking a step back, it is nonsensical for the outer class to want to access a stateful property of some arbitrary instance of the nested class. There's no reason for an arbitrary instance's state to be useful. The only reason the outer class would need to access a property of the other class is if it is doing something with a specific instance of the inner class, in which case it would already have an instance of it on which to access its property.
In your example code, the nested class is weird because it defines a property that can only ever hold a value of 2. So every instance of the class is reserving memory for a property to hold a duplicate of that same value, even though it should really be a constant that is shared by all instances.
If the value you want to access is a constant (the same value for all instances), then it would make sense to want to access it regardless of instance because it doesn't have anything to do with a specific instance. To make it constant, it should be defined in a companion object like this. Then it can be accessed through the name of the nested class without creating an instance of it.
class ExternalClass {
class InternalClass {
companion object {
val internalValue = 2
}
}
val externalValue = InternalClass.internalValue
}
An interface would have nothing to do with this kind of thing.

Mark Haxe Class for forced extend?

Is there a compiler meta for Class declaration, that prevents creating Class instance before extending it? In other words - some sort of opposite of #:final meta.
Like so (last line of code):
class A {
// ...
}
class B extends A {
// ...
}
// ...
var b = new B(); // OK
var a = new A(); // induce compiler-error
Simply don't declare a constructor at all for class A
Both the other answers are correct (no constructor or private constructor), but there are a few more details that you may interest you:
Here's an example of no constructor. Of note is that A simply doesn't have a constructor, and B simply doesn't call super(). Other than that, everything else works as you'd expect.
Here's an example of a private constructor. You still can't instantiate a new A(), but you do still need to call super() from B's constructor.
Technicalities:
Use of some features (like a default value on a member variable) will cause A to get an implicit constructor, automatically. Don't worry, this doesn't affect constructability or whether you need to call super(). But know that it is there, and if necessary an implicit super() call is prepended to B's constructor. See the JS output to verify this.
In any case, know that you can still instantiate an A at runtime with var a = Type.createInstance(A,[]); as compile-time type checks do not limit RTTI.
Related discussion:
Aside from private/no constructor, Haxe doesn't have a formal notion of abstract classes1 (base classes not expected to be instantiated) or abstract methods2 (functions on abstract base classes with no implementation that must be implemented by a derived class.) However, Andy Li wrote a macro for enforcing some of those concepts if you use them. Such a macro can detect violations of these rules and throw compile-time errors.
1. Not to be confused with Haxe abstracts types, which are an entirely different topic.
2. Not to be confused with virtual functions, which wikipedia describes as a function which can be overridden (though various docs for various languages describe this highly loaded term differently.)
One way of achieving this is to create private Class constructor:
class A {
private function new() {
// ...
}
}
// ...
var a = new A(); // Error: Cannot access private constructor

Error when inheriting from Ektron.Cms.Content.Targeting.Rules.RuleTemplate

I have a C# class called MyCustomRuleTemplate which is inherited from Ektron.Cms.Content.Targeting.Rules.RuleTemplate class. In that I have added a constructor such as below
public MyCustomRuleTemplate(): base("someKey")
{
//Some code here
}
Its working fine without any error. If I given it as
public MyCustomRuleTemplate()
{
//Some code here
}
Im getting error like 'Ektron.Cms.Content.Targeting.Rules.RuleTemplate' does not contain a constructor that takes 0 arguments.
Can anybody help me to know why it is?
The reason you are seeing "does not contain a constructor that takes 0 arguments" when instantiating your class object using the second constructor is because when you call your constructor, c# tries to call the constructor on the base class as well, which in this case takes a parameter.
See this post on msdn:
http://msdn.microsoft.com/en-us/library/ms173115%28v=vs.80%29.aspx
Key parts:
"In this example, the constructor for the base class is called before the block for the constructor is executed. The base keyword can be used with or without parameters. Any parameters to the constructor can be used as parameters to base, or as part of an expression. For more information, see base.
In a derived class, if a base-class constructor is not called explicitly using the base keyword, then the default constructor, if there is one, is called implicitly."
And: "If a base class does not offer a default constructor, the derived class must make an explicit call to a base constructor using base."

Scala instance value scoping

Note that this question and similar ones have been asked before, such as in Forward References - why does this code compile?, but I found the answers to still leave some questions open, so I'm having another go at this issue.
Within methods and functions, the effect of the val keyword appears to be lexical, i.e.
def foo {
println(bar)
val bar = 42
}
yielding
error: forward reference extends over definition of value bar
However, within classes, the scoping rules of val seem to change:
object Foo {
def foo = bar
println(bar)
val bar = 42
}
Not only does this compile, but also the println in the constructor will yield 0 as its output, while calling foo after the instance is fully constructed will result in the expected value 42.
So it appears to be possible for methods to forward-reference instance values, which will, eventually, be initialised before the method can be called (unless, of course, you're calling it from the constructor), and for statements within the constructor to forward-reference values in the same way, accessing them before they've been initialised, resulting in a silly arbitrary value.
From this, a couple of questions arise:
Why does val use its lexical compile-time effect within constructors?
Given that a constructor is really just a method, this seems rather inconsistent to entirely drop val's compile-time effect, giving it its usual run-time effect only.
Why does val, effectively, lose its effect of declaring an immutable value?
Accessing the value at different times may result in different results. To me, it very much seems like a compiler implementation detail leaking out.
What might legitimate usecases for this look like?
I'm having a hard time coming up with an example that absolutely requires the current semantics of val within constructors and wouldn't easily be implementable with a proper, lexical val, possibly in combination with lazy.
How would one work around this behaviour of val, getting back all the guarantees one is used to from using it within other methods?
One could, presumably, declare all instance vals to be lazy in order to get back to a val being immutable and yielding the same result no matter how they are accessed and to make the compile-time effect as observed within regular methods less relevant, but that seems like quite an awful hack to me for this sort of thing.
Given that this behaviour unlikely to ever change within the actual language, would a compiler plugin be the right place to fix this issue, or is it possible to implement a val-alike keyword with, for someone who just spent an hour debugging an issue caused by this oddity, more sensible semantics within the language?
Only a partial answer:
Given that a constructor is really just a method ...
It isn't.
It doesn't return a result and doesn't declare a return type (or doesn't have a name)
It can't be called again for an object of said class like "foo".new ("bar")
You can't hide it from an derived class
You have to call them with 'new'
Their name is fixed by the name of the class
Ctors look a little like methods from the syntax, they take parameters and have a body, but that's about all.
Why does val, effectively, lose its effect of declaring an immutable value?
It doesn't. You have to take an elementary type which can't be null to get this illusion - with Objects, it looks different:
object Foo {
def foo = bar
println (bar.mkString)
val bar = List(42)
}
// Exiting paste mode, now interpreting.
defined module Foo
scala> val foo=Foo
java.lang.NullPointerException
You can't change a val 2 times, you can't give it a different value than null or 0, you can't change it back, and a different value is only possible for the elementary types. So that's far away from being a variable - it's a - maybe uninitialized - final value.
What might legitimate usecases for this look like?
I guess working in the REPL with interactive feedback. You execute code without an explicit wrapping object or class. To get this instant feedback, it can't be waited until the (implicit) object gets its closing }. Therefore the class/object isn't read in a two-pass fashion where firstly all declarations and initialisations are performed.
How would one work around this behaviour of val, getting back all the guarantees one is used to from using it within other methods?
Don't read attributes in the Ctor, like you don't read attributes in Java, which might get overwritten in subclasses.
update
Similar problems can occur in Java. A direct access to an uninitialized, final attribute is prevented by the compiler, but if you call it via another method:
public class FinalCheck
{
final int foo;
public FinalCheck ()
{
// does not compile:
// variable foo might not have been initialized
// System.out.println (foo);
// Does compile -
bar ();
foo = 42;
System.out.println (foo);
}
public void bar () {
System.out.println (foo);
}
public static void main (String args[])
{
new FinalCheck ();
}
}
... you see two values for foo.
0
42
I don't want to excuse this behaviour, and I agree, that it would be nice, if the compiler could warn consequently - in Java and Scala.
So it appears to be possible for methods to forward-reference instance
values, which will, eventually, be initialised before the method can
be called (unless, of course, you're calling it from the constructor),
and for statements within the constructor to forward-reference values
in the same way, accessing them before they've been initialised,
resulting in a silly arbitrary value.
A constructor is a constructor. You are constructing the object. All of its fields are initialized by JVM (basically, zeroed), and then the constructor fills in whatever fields needs filling in.
Why does val use its lexical compile-time effect within constructors?
Given that a constructor is really just a method, this seems rather
inconsistent to entirely drop val's compile-time effect, giving it its
usual run-time effect only.
I have no idea what you are saying or asking here, but a constructor is not a method.
Why does val, effectively, lose its effect of declaring an immutable value?
Accessing the value at different times may result in different
results. To me, it very much seems like a compiler implementation
detail leaking out.
It doesn't. If you try to modify bar from the constructor, you'll see it is not possible. Accessing the value at different times in the constructor may result in different results, of course.
You are constructing the object: it starts not constructed, and ends constructed. For it not to change it would have to start out with its final value, but how can it do that without someone assigning that value?
Guess who does that? The constructor.
What might legitimate usecases for this look like?
I'm having a hard time coming up with an example that absolutely
requires the current semantics of val within constructors and wouldn't
easily be implementable with a proper, lexical val, possibly in
combination with lazy.
There's no use case for accessing the val before its value has been filled in. It's just impossible to find out whether it has been initialized or not. For example:
class Foo {
println(bar)
val bar = 10
}
Do you think the compiler can guarantee it has not been initialized? Well, then open the REPL, put in the above class, and then this:
class Bar extends { override val bar = 42 } with Foo
new Bar
And see that bar was initialized when printed.
How would one work around this behaviour of val, getting back all the
guarantees one is used to from using it within other methods?
Declare your vals before using them. But note that constuctor is not a method. When you do:
println(bar)
inside a constructor, you are writing:
println(this.bar)
And this, the object of the class you are writing a constructor for, has a bar getter, so it is called.
When you do the same thing on a method where bar is a definition, there's no this with a bar getter.

Scala: invoking superclass constructor

I am experiencing a weird behavior by Scala handling of superclass constructors.
I have a really simple class defined in the following way
package server
class Content(identifier:String,content:String){
def getIdentifier() : String = {identifier}
def getContent() : String = {content}
}
and a simple subclass
package server
class SubContent(identifier:String, content:String) extends Content(identifier, content+"XXX")){
override def getContent():String = {
println(content)
super.getContent
}
}
What's really strange is that in the subclass there are duplicates of the superclass attributes, so if i create a new object
var c = new SubContent("x","x")
the execution of
c.getContent
first prints out "x" (The valued provided to the subclass constructor), but returns "xXXX" (The value provided to the superclass constructor).
Is there any way to avoid this behavior? Basically what I'd like to have is that the subclass does not create its own attributes but rather just passes the parameters to the superclass.
It's doing exactly what you told it to do. You augmented the 2nd constructor parameter when passing it on to the superclass constructor and then you used the superclass' getContent to provide the value returned from the subclass' getContent.
The thing you need to be aware of is that constructor parameters (those not tied to properties because they're part of a case class or because they were declared with the val keyword) are in scope throughout the class body. The class' constructor is that part of its body that is outside any method. So references to constructor parameters in method bodies forces the constructor parameter to be stored in a field so it can have the necessary extent. Note that your println call in getContent is causing such a hidden constructor parameter field in this case.
Replying to comment "Is there an alternative way to define it in order to avoid this? Or at least, if I never refer to the parameters of the subclass constructors their fields will be allocated (Wasting memory)?":
If the only references to plain constructor parameters (*) is in the constructor proper (i.e., outside any method body, and val and var initializers don't qualify as method bodies) then no invisible field will be created to hold the constructor parameter.
However, If there's more you're trying to "avoid" than these invisible fields, I don't understand what you're asking.
(*) By "plain constructor parameters" I mean those not part of a case class and not bearing the val keyword.