I'm using YII and have liberally set #property phpdoc statements to all my models.
In my IDE (phpstorm), I can Control + Click methods and fields to be taken to their implementations, but when I do so for magic methods, it takes me to the top of the class definition, which is incorrect.
How can I set it up so that it takes me to the associated getter method?
What I understand it that
#property and #method methods tags are only allowed in the class-level docblock.Both of these tags gives hint to developer about availability about methods/properties implemented through megic methods __call($method,$params), __get($var) and __set($var,$val).
In yii you don't need to define getter/setter methods explicitly for class attributes. So an attributes is access through 'get'.$attributeName e.g
/**
* Class User
*
* #method string getFirstName()
* #method void setFirstName(string $firstName)
*
*/
class User extends CModel{
var $firstName;
}
$u= new User();
$username=$u->getFirstName();
$u->setFirstName('Testuser');
In the context of Yii , the above code is true bcz of magic method 'get'.$attributeName for call attributes.
Since #property and #method are class level #tags your only bet is to add them to class and Ctrl+click will send focus to respective class docblock
Related
Most of the implementations of Builder pattern I have seen are along these lines:
https://github.com/Design-pattrns/Builder-Pattern/blob/master/src/Computer.java
Basically the nested builder class needs to mirror all the attributes of the class that we need to build objects of and then provide methods to set the said attributes and an additional build() method inside the builder class.
When I tried to implement builder on my own, I came up with this (I use an instance of Person object inside builder instead of copying all the attributes of the Person class)
public class Person {
private String firstName;
private String lastName;
public static class PersonBuilder{
private Person person = new Person();
public PersonBuilder firstName(String firstName){
person.firstName = firstName;
return this;
}
public PersonBuilder lastName(String lastName){
person.lastName = lastName;
return this;
}
public Person build(){
return person;
}
}
}
Benefits:
1). No need to repeat the attributes of the class we want to instantiate
2). build method is simplified, just need to return the person object.
3). The Person class need not have a constructor which takes the Builder object as argument
4). More easily "updatable". If new attributes are added to person class, all we need
to do is add the set method inside the builder class if needed. No need to
create another attribute.
Cons:
1). The person object is eager initialised?
So are there any issues with this implementation?
I would say the example above is "simpler" but it has none of the advantages a builder offers and its probably better to just use the new keywords where you need the object and adding the properties to the constructor. Id say the drawbacks compared to the builder are as follows:
it can only make a single instance
once the builder has "finished" it can continue to interact with the object as it still holds a reference to it.
its very tightly coupled to the product it is "building".
the fact that the person class has to expose a lot of properties as mutable for the builder, which you might want to not be mutable elsewhere in the code.
Its actually more of a configurator, I would not advise this pattern however you could pass the object to be configured into the constructor. In which case I would create two interfaces
IConfigurablePerson which includes the setters
IPerson which includes the getters
Give the configurator IConfigurablePerson to its constructor, so it can access the setters then give other classes IPerson with only the getters. The advantage this offers is that it can work with multiple implementations of IConfigurablePerson without needing to know the class its working with (decoupling).
In Swift, what is the conventional way to define the common pattern where a property is to be externally readonly, but modifiable internally by the class (and subclasses) that own it.
In Objective-C, there are the following options:
Declare the property as readonly in the interface and use a class extension to access the property internally. This is message-based access, hence it works nicely with KVO, atomicity, etc.
Declare the property as readonly in the interface, but access the backing ivar internally. As the default access for an ivar is protected, this works nicely in a class hierarchy, where subclasses will also be able to modify the value, but the field is otherwise readonly.
In Java the convention is:
Declare a protected field, and implement a public, read-only getter (method).
What is the idiom for Swift?
Given a class property, you can specify a different access level by prefixing the property declaration with the access modifier followed by get or set between parenthesis. For example, a class property with a public getter and a private setter will be declared as:
private(set) public var readonlyProperty: Int
Suggested reading: Getters and Setters
Martin's considerations about accessibility level are still valid - i.e. there's no protected modifier, internal restricts access to the module only, private to the current file only, and public with no restrictions.
Swift 3 notes
2 new access modifiers, fileprivate and open have been added to the language, while private and public have been slightly modified:
open applies to class and class members only: it's used to allow a class to be subclassed or a member to be overridden outside of the module where they are defined. public instead makes the class or the member publicly accessible, but not inheritable or overridable
private now makes a member visible and accessible from the enclosing declaration only, whereas fileprivate to the entire file where it is contained
More details here.
As per #Antonio, we can use a single property to access as the readOnly property value publicly and readWrite privately. Below is my illustration:
class MyClass {
private(set) public var publicReadOnly: Int = 10
//as below, we can modify the value within same class which is private access
func increment() {
publicReadOnly += 1
}
func decrement() {
publicReadOnly -= 1
}
}
let object = MyClass()
print("Initial valule: \(object.publicReadOnly)")
//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible"
//object.publicReadOnly += 1
object.increment()
print("After increment method call: \(object.publicReadOnly)")
object.decrement()
print("After decrement method call: \(object.publicReadOnly)")
And here is the output:
Initial valule: 10
After increment method call: 11
After decrement method call: 10
i need to implement the message markedSubclass in pharo that works just like subclass but i need the class that gets created to be somehow marked,for example i tried adding a unique instance variable to it after creating it but it's just not working,maybe i'm adding it to a wrong place.
the requirments are:
every subclass of this marked class should also be marked even if it
was created via subclass (not markedSubclass).
other than that a marked class should function just as a regular class should.
any help would be appreciated.
example:
User markedSubclass: #MarkedUser
User subClass: #UnmarkedUser
MarkedUser subclass: #MarkerUser2
i need to somehow know that MarkedUser and UnmarkedUser are both marked classes.
what i thought of lately is adding the method "isMarked" to Class class and this way all
the classes will have it, and each class will override it accordingly so if we write
User class isMarked.
it will return false but if we write:
MarkedUser class isMarked.
MarkedUser2 class isMarked.
it will return true for both.
but where can i add this method?and how can i make a class override the method in runtime?
Add a class method like the following to your User class:
markedSubclass: className
| subclass |
subclass := self subclass: className asSymbol.
subclass class compile: 'isMarked', String cr, String tab, ' ^ true'.
^ subclass
Then try in a workspace:
User markedSubclass: 'MyMarkedSubclass'
Add an #unmarkedSubclass: class method accordingly.
You could then override the general #subclass: method in your User class to set the same marker as the receiver.
When declaring a class/instance property, I am accustomed to doing something like this:
class MyClass
{
protected
/** #var SplDoublyLinkedList */
$_nodes;
}
In the example above, I would expect my IDE (PhpStorm in my case) to show me code completion for the SplDoublyLinkedList class any time I typed $this->_nodes-> anywhere inside the class declaration.
This doesn't appear to be occurring, though. Is this a a problem with PhpStorm, or am I just not doing it right?
EDIT: I've submitted a feature request on YouTrack.
try
class MyClass
{
/** #var SplDoublyLinkedList */
protected
$_nodes;
}
I'm declaring a family of static classes that deals with a communications protocol. I want to declare a parent class that process common messages like ACKs, inline errors...
I need to have a static var that mantain the current element being processed and I want to declare it in the parent class.
I do it like this:
parent.m
#implementation ServerParser
static NSString * currentElement;
but the subclasses are not seing the currentElement.
If you declare a static variable in the implementation file of a class, then that variable is only visible to that class.
You could declare the static variable in the header file of the class, however, it will be visible to all classes that #import the header.
One workaround would be to declare the static variable in the parent class, as you have described, but also create a class method to access the variable:
#implementation ServerParser
static NSString *currentElement;
...
+ (NSString*)currentElement
{
return currentElement;
}
...
#end
Then, you can retrieve the value of the static variable by calling:
[ServerParser currentElement];
Yet the variable won't be visible to other classes unless they use that method.
A workaround would be to declare the static variable in the implementation of the parent class AND also declare a property in the parent class.
Then in the accessor methods access the static variable. This way you can access static variables like properties with dot syntax. All the subclasses access the same shared static variable.
More simple. Create a pre Base class, with protected static variable. For example:
public abstract class preBase {
protected static int VariableStaticPrivate;
}
public abstract class Base : preBase{
//Inherit VariableStaticPrivate
//And you can use it.
}
public class DerivedOne : Base {
//Also inherit VariableStaticPrivate
//And you can use it.
}