I use a Lumen Laravel-based framework and it allows me to create custom method like this:
/**there should be a proper doc*/
\Laravel\Lumen\Http\ResponseFactory::macro('customMethod', function ()
{
return $this;
});
It creates method customMethod called as method which belongs response() function.
/**or probably there should be a proper doc*/
return response()->customMethod()
I want to make a hint to my IDE (PhpStorm 2020.1.2) which allows it to see reference from where customMethod is called to where it is declared, and follow it with click on function name in IDE.
Related
I want to check that if a member function of a particular name exists on a object, if it does call the member function or make a reference of that member function.
Here I don't have type of the object, i.e. the object maybe does not implement any interface but has a member function cancel().
I used this method (reflection) to check if the member function exists, i.e. if (object::class.members.any { it.name == "cancel" }) and when this statement returns true I am sure that the method does exist but compiler is still unsure that the 'cancel' method exist in the object or not
fun canceller(object: Any): KFunction<Any>?
{
var canceller: KFunction<Any>? = null
// check if object has member function 'cancel'
if (object::class.members.any { it.name == "cancel" })
{
// make reference of that member function and return it
canceller = object::cancel //cancel is still not recognized as a member function and gives an error that "Unresolved reference: cancel"
// or just call it now
// object.cancel()
}
return canceller
}
I expect that canceller variable should be assigned to value.cancel(), but the compiler is unsure that cancel() function exist (with an error "Unresolved reference: cancel") in the object even after we supplied a check inside if statement
It's not meant to be used like this. Reflection is something you use if you don't know at compile time what you are dealing with at runtime. Some examples:
you need to use a type that's configured in some properties file (Class.forName("someTypeString").newInstance())
you have written an utility that extracts the contents of your object for debugging purposes
you need to access code that isn't really visible to you (private fields that you can't easily access, but you need to)
many more... but most of the time very special use-cases
Now what you have shown is a function reference (object::cancel). In order to use a function reference the compiler must know the type of object and the cancel-function must exist for that type. As object is of type Any and the if-condition is only relevant at runtime, the compiler does not know that there is a cancel-function available and therefore compilation fails.
Note that if you aren't doing anything special, you should rather check for a common type/interface. So for example, if your objects implement an interface Cancellable you could just change your code to something as follows:
fun canceller(object: Any): KFunction<Any>? {
var canceller: KFunction<Any>? = null
// check if object is of type Cancellable
if (object is Cancellable) {
// make reference of the Cancellable::cancel-function
canceller = object::cancel // smart-cast acting
// or you could also call it directly: object.cancel()
}
return canceller
}
or probably you could just spare that function altogether and end up with something like just:
val someObj : Cancellable = ...
// somewhere later:
someObj.cancel()
Reflection is rather expensive and if you aren't entirely sure what it is useful for, you should not use it.
If you really knew what you were doing... then ok... it's of course also possible to call that function via reflection and if you ask for the existance of a function via reflection you also have to call it via reflection:
object::class.members.first {
// note: I am using just the first function... if there are several, you need to check which one to use (parameter/type)
it.name == "cancel"
}
.call(object)
I think you can use reflections for this purpose.
myObject.javaClass.kotlin.members.any { it.name == "cancel" }
And the better way to express the idea of "object that has all the variables" is to define the interface and have all those object implemented
interface Achiever { val name: String }
I'm trying to get the reserved keyword arguments array from inside a static method and I'm getting this error:
1042: The this keyword can not be used in static methods. It can only
be used in instance methods, function closures, and global code.
Here is my code:
public static function doSomething(message:String, ...Arguments):void {
var object:Object = this.arguments.caller;
}
If I take the this keyword out then I get the following error:
1120: Access of undefined property arguments.
this is reserved to reference the current instance of a class which unfortunately doesn't exist inside a static function (since static function is not tied to an instance).
You could try using the new rest keyword if you want to pass in an unknown number of arguments:
ActionScript 3.0 includes a new ...(rest) keyword that is recommended instead of the arguments class.
However if you want it just to get the caller function:
Unlike previous versions of ActionScript, ActionScript 3.0 has no arguments.caller property. To get a reference to the function that called the current function, you must pass a reference to that function as an argument. An example of this technique can be found in the example for arguments.callee.
public function test() {
doSomething("Hello", arguments.callee);
}
public static function doSomething(message:String, caller:Function):void {
var object:Object = caller;
}
You could get the arguments of a static method. From the documentation:
Within a function's body, you can access its arguments object by using the local arguments variable.
You do not need the this keyword, this references to the Class instance instead to the function itself:
public static function doSomething():void {
return arguments;
}
Next you can access to the arguments calling the static method:
var arguments:Object = MyClass.doSomething();
trace( arguments.callee );
But remember, like #MartinKonecny said, in AS3 is better use the ...rest keyword or pass a function reference as an argument.
The arguments object is available in static functions but is not available when using the ...rest parameter.
Use of this parameter makes the arguments object unavailable. Although
the ... (rest) parameter gives you the same functionality as the
arguments array and arguments.length property, it does not provide
functionality similar to that provided by arguments.callee. Make sure
you do not need to use arguments.callee before using the ... (rest)
parameter.
Take out the ...rest parameter and the arguments object appears.
Also, the this keyword is not always necessary.
method.apply(this, args);
may throw an error in a static function but the parameter is optional so this also works:
method.apply(null, args);
More on the rest keyword.
Some times ago I wrote a component that I find very convenient to use instead of other kind of authorization tools. I have converted it to CakePHP 3 and it still suits perfectly to my needs, but now I need to call one of its functions from a helper, and I can't figure out how to do that. The component name is PermissionsComponent.
Here is a draft of my helper:
namespace App\View\Helper;
use Cake\View\Helper;
use App\Controllers\Component\PermissionsComponent;
class PermissionsHelper extends Helper {
function check($action, $redirect = false) {
// how can I call my component's action check($action, $redirect)?
}
}
How can I call that component's action from a helper?
You can't. It sounds more like you should use another object that you can use in both the component and the helper.
// In PermissionsComponent
$permissions = new Permissions();
...
$this->_controller->set('_permissions', $permissions);
And then you can use it in your helper:
// In PermissionsHelper
$permissions = $this->_View->get('_permissions');
I have a overriden function in my class, that adds an event handler like so:
override public function hide():void {
...
tween.addEventListener(TweenEvent.MOTION_FINISH, function(evt:Event):void {
...
super.hide();
}, false, 0, true);
}
This does not work, Flash tells me: "1006: A super expression can be used only inside class instance methods." (it works if moved to a proper instance method).
So I would like to understand why can't I use call to super.hide(); from my in-place handler function?
I can refer to any instance variables and methods from there without problems, so I thought that that handler had access to proper context.
Please help me understand this.
it is, because this in an anonymous function points to [object global] ... have a go, and trace it ...
now an AS3 feature is, that you can access instance members from inside there, but that's a really strange feature ... this.myProp will not work, whereas myProp will ... this is some dark magic, that automatically creates a closure ... for some reason it works with instance members, but not with super ...
IMHO, you should not use anonymous functions anyway, only if it is for prototyping, or as parameters for Array methods as forEach, map, filter and the like ...
greetz
back2dos
I believe you can capture the method in a variable that gets stored in the anonymous method's closure. For instance:
override public function hide():void {
...
var f:Function=super.hide;
tween.addEventListener(TweenEvent.MOTION_FINISH, function(evt:Event):void {
...
f();
}, false, 0, true);
}
I can explain further if you are struggling with the concept of closure.
How does one get a reference the the getter and setter functions in actionscript 3?
if a method is defined on the calls, e.g.
public function blah():String { ...}
I can get a reference to it by just saying blah or this.blah
How do get a reference to
public function get blah2():String {}
public function set blah2(b:String):void {}
Thanks!
Original response:
Unfortunately, you will not be able to store references to those as functions. The getter and setter methods are actually built around the idea that you shouldn't be able to and they therefore function as a property.
Is there a reason that you need to reference the functions specifically?
The comment I'm responding to:
I want to dynamically add external interface methods based on custom metadata tags, e.g. [External]. I was able to do this for the regular methods, but I'm trying to extend this to getter/setters as well. To do this, I need to get a reference to the function dynamically, so I can execute it with the right args using the apply function.
I think you're better off using a multi-step approach in that case. Since getters and setters function as a property and not a method, it would make sense to test to see if it is a property and then simply assign it a value directly. Would you be able to use this:
if( foo.blah2 is Function )
{
foo.blah2.apply( foo, arr );
}
else
{
foo.blah2 = arr[ 0 ];
}