PHP set class property to a std object in class defination [duplicate] - oop

This question already has answers here:
Initializing PHP class property declarations with simple expressions yields syntax error
(3 answers)
Closed 9 years ago.
Is there a way in PHP the class definition to have a property set to a STD object with set properties?
I was thinking you can type cast but its not allowed for properties in the class definition.
//example.
class Foo{
private static $Obj = (object) ['bizz', 'bazz'];
}
which will trigger this error:
Parse error: syntax error, unexpected '(object)' (object) (T_OBJECT_CAST)

You cannot assign non-constant values to class properties during declaration. From http://php.net/language.oop5.properties
...initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
You will need to use a class method to initialise the property, eg
class Foo {
private static $Obj;
private static getObj() {
if (null === self::$Obj) {
self::$Obj = (object) ['bizz', 'bazz'];
}
return self::$Obj;
}

Related

Exposing an object variable as public makes its members unresolvable

I have a Kotlin class with a member object:
private var strings = object { var foo = ""; var bar = "" }
Inside my class's functions, I can reference strings.foo and strings.bar.
But when I make strings a public var, suddenly all of its members become "unresolved references". Why?
class Foo {
// Making this `private` fixes the errors below for some reason
public var strings = object {
var foo = ""
var bar = ""
}
fun initialize() {
strings.foo = getFoo() // "Unresolved reference: foo"
strings.bar = getBar() // "Unresolved reference: bar"
}
}
(What I'm trying to do here is expose a whole bunch of string resources as constants so I don't have to use the literal string values throughout my code. I'm actually using lateinit var for each member but that doesn't change the result here.)
strings is defined with an object literal. You probably want to use an regular object declaration instead:
object Strings {...}
strings = Strings()
With the object literal, strings is an anonymous object whose type is "usable (and visible) only in the scope where it is declared".
without any explicitly declared supertype, menaing Any is implicit super type of this object.
When you make strings a public var, it escapes the current scope and is implicitly downcasted to its supertype; without any explicitly declared supertype, the supertype is Any, so of course you get errors trying to reference the properties foo and bar.
From Kotlin spec
The main difference between a regular object declaration and an anonymous object is its type. The type of an anonymous object is a special kind of type which is usable (and visible) only in the scope where it is declared. It is similar to a type of a regular object declaration, but, as it cannot be used outside the declaring scope, has some interesting effects.
When a value of an anonymous object type escapes current scope:
If the type has only one declared supertype, it is implicitly downcasted to this declared supertype;
If the type has several declared supertypes, there must be an implicit or explicit cast to any suitable type visible outside the scope, otherwise it is a compile-time error.
Note: an implicit cast may arise, for example, from the results of type inference.
Note: in this context “escaping current scope” is performed immediately if the corresponding value is declared as a non-private global- or classifier-scope property, as those are parts of an externally accessible interface.
You could also use a Companion object:
companion object Strings {
var foo = ""
var bar = ""
}
fun init(){
foo = getFoo()
bar = getBar()
}

How to instantiate an object that implements a java interface? (that is, 2 lambdas) [duplicate]

This question already has answers here:
How to create an instance of anonymous interface in Kotlin?
(5 answers)
Closed 2 years ago.
I have this Java interface:
public interface MetronomeCallback {
void onTick(boolean tickValue);
void onBPM(int bpm);
}
public void setMetronomeCallback(MetronomeCallback metronomeCallback) {
this.metronomeCallback = metronomeCallback;
}
This is a lambda function in java, I'm supposed to pass an object to setMetronomeCallback that implements these 2.
I want to implement it inline, like this:
val metronomeCallback = MainService.MetronomeCallback {
fun onTick(value: Boolean) {
}
fun onBPM(bpm: Int) {
}
}
s.setMetronomeCallback(metronomeCallback);
How to create an object that implement these 2 functions?
It's obvious when you know: to create an object that implements some interface, you use object : Interface { … }.
So in this case, I think you just need to insert object : before the interface name.
(You can extend a class similarly; you just need to add parens and any constructor parameters after the classname.  And you can inherit from multiple interfaces/classes, by separating them with a comma.)
The technical term for this is an object expression; it's all explained in the language docs.

::property.isInitialized cannot differentiate between method and property with same name

I'm creating a builder (for Java compat), where context is both a private property and public method.
private lateinit var context: Context
fun context(appContext: Context) = apply {
context = appContext
}
fun build(): MySdk {
// this::context fails to compile because it cannot differentiate between the
// method `context()` vs property `context`
require(this::context.isInitialized) {
"context == null"
}
But I get a compilation issue for ::context.isInitialized, because it cannot differentiate between the method context() vs property context
Does Kotlin have a workaround for this? or am I forced to use unique property/method names?
This is a case of overload resolution ambiguity and the kotlin compiler is unable to identify whether you are using the property or the method.
This is because of callable references (::) . Internally when you are using the callable references it calls a method.
Callable references : References to functions, properties, and
constructors, apart from introspecting the program structure, can also
be called or used as instances of function types.
The common supertype for all callable references is KCallable, where R is the return value type, which is the property type for properties, and the constructed type for constructors.
KCallable<out R> // supertype for all callable references
So, for function the type is KFunction and for properties the type is KProperty
interface KFunction<out R> : KCallable<R>, Function<R> (source)
interface KProperty<out R> : KCallable<R> (source)
When you use a function like :
fun context(appContext: Context) = apply {
context = appContext
}
It can be used as a Function reference
::context // This is a Function reference i.e. KFunction
When you use a property reference, like
private lateinit var context: Context
fun something(){
::context // this is a property reference, KProperty
}
A property reference can be used where a function with one parameter is expected:
val strs = listOf("a", "bc", "def")
println(strs.map(String::length))
So, its not that Kotlin forces you to use different property and function names("although it is not recommended"). Its just that its unable to differentiate in this case as
Both are KCallable and have the same name
A property reference can be used where a function with one parameter is expected
You can resolve the ambiguity between the property and the method by giving the expected type:
val prop: kotlin.reflect.KProperty0<*> = this::context
Alas, prop.isInitialized then gives a compilation error:
This declaration can only be called on a property literal (e.g. 'Foo::bar')
So this doesn't appear to be possible currently. OTOH, since the error shows isInitialized is already handled specially by the compiler, it's likely possible to fix; I suggest reporting it on http://youtrack.jetbrains.com/ (after searching for duplicates).

'never' properties cannot be set inside the counstructor

So, the question is in the title. I declared some properties in my classes using 'never' keyword so I may set the values of these properties only once, in the constructor. However, I get the following error:
Cannot access field or identifier %name% for writing
Example of the problematic code:
class TreeAbility
{
public var id(default, never):String;
public var maxLvl(default, never):Int;
public function new(id:String, maxLvl:Int)
{
Assert.assert(maxLvl > 0);
this.id = id; (*)
this.maxLvl = maxLvl; (*)
this.currentLvl = 0;
}
}
The lines marked with (*) throw the access error
I believe the never write property means that writing/setting the variable is never allowed, not even within the constructor. See: https://haxe.org/manual/class-field-property.html
Perhaps you are looking for the final keyword, which is coming in Haxe 4. For instance fields, it allows assignment to the variable only from the class constructor. Confirmed here: https://haxe.org/download/version/4.0.0-preview.2/ and https://github.com/HaxeFoundation/haxe/issues/6584

Not declaring a property as optional results in "property not initialized at super.init()" error [duplicate]

This question already has answers here:
Error in Swift class: Property not initialized at super.init call
(12 answers)
Closed 8 years ago.
I have written the following code for a protocol. I pass the the reference to the delegate variable and use it to call interface/protocol functions. However, if I put ? for declaring the Protocol object, no error is generated. If I don't, it gives me an error
property self.delegate is not intialized at super.init().
Why is that?
protocol DownloadDataInterface
{
func downloadCompleted(data : NSDictionary);
}
class DownloadData: NSObject, NSURLConnectionDelegate, NSURLConnectionDataDelegate {
var data : NSMutableData!;
var delegate : DownloadDataInterface;
init(keywords: String!)
{
super.init();
Because by the end of the init every property must have been initialized. Either at the declaration site or within the code of the init.
Properties that are optional or implicitly unwrapped optional are the only exception (because, after all, that's what being optional means).