For example, there are functions named -(void)Foo, and -(void)Foo:(id)sender.
The -(void)Foo:(id)sender can get the caller from parameter, and my question is, how to get caller from -(void)Foo? Is there any way to get the caller?
Please have a look at Objective C find caller of method. For what do you need it? The (id)sender parameter is passed directly by the method sending the message, there is no magic involved.
Related
Although there is a documentation available, I got more confused, rather then enlightened. Let's consider an example:
I have a myObject instance, which has myMethod method and I call it from the lobby:
myObject myMethod
In this method's body following is done:
myObject1 anotherMethod //1
msg := message(anotherMethod)
myObject2 do(msg) //2
myObject3 doMessage(msg) //3
So, could anyone explain me differences between 1 2 and 3?
Who is the actual caller for these cases? The locals object of the method, the method object or myObject? Is there a difference between sender and caller (I suppose there is one in case of doMessage, where sender is the locals object of the myMethod, but the "caller" is myObject3)
Alright, so in order:
The message anotherMethod is received by the instance named myObject. This is done in the calling context (probably the Lobby, unless wrapped inside another do()
do() introduces a new scope, and does nothing with the calling scope. That is to say, you can't reference anything in the calling scope inside a do() unless it happens to be in the Protos hierarchy or introduced inside the do(). do() also takes a message tree, and so what you're doing is effectively sending message(msg) to be evaluated inside the context of myObject which doesn't make much sense since msg first off can't be found due to the scope not being available, and even if it was, wouldn't make a lot of sense. Generally, you want to do something like: msg doInContext(myObject) if you find yourself desiring to write myObject do(msg).
Is functionally equal to #1 above. In fact, if you were to write a compiler for Io code down to messages, this is more or less what you'd get out of that compilation step of #1. They're equivalent in this short example.
I got this error on one of my object calls, I don't get what it even means:
Class::XSAccessor: invalid instance method invocant: no hash ref supplied
Check whether you are making a class method call where Class::XSAccessor is expecting an instance method call.
In other words, the error message means what it says--it expects a blessed hash ref, and you didn't give it one.
In my case, the problem was that I was doing a $package_name->method call; what was needed was for me to make the same call against an instance of the class. So, for my situation, it was sufficient to simply do $package_name->new()->method.
I'm using Eclipse JDT AST to parse a given java source code. While parsing the code, when it hits a method invocation, I want to find out whether that particular method returns or sets a value of an instance variable (basically to find out whether the callee method is a getter/setter of the same class of caller method).
E.g.:
public void test(){
//when parsing the following line I want to check whether "getName"
//returns a value of an instance variable.
String x = getName();
//when parsing the following line I want to check whether "setName"
//sets the value of an instance variable.
setName("some-name");
}
I've used the AST plugin also find out a possible path which would help me to refer it from the API, but couldn't.
Please let me know whether this is possible and if so, which approach that would help me to get the required information.
Don't think that there is an api which tells you whether a method is a getter or a setter.
You will have to write code to do this. For a getter, you can probably simply check if the last statement in the method is a return statement which returns an instance variable.
Normally, to call a method from its reference, it should go something like below:
$methodref->(#args)
But when invoke a method from its reference returned from "can", it seems inconsistent.
$methodref = $my_obj->can(my_method);
$my_obj->$methodref(#args) if $methodref; # why it isn't $my_obj->$methodref->(#args)?
Can someone please shed some light on this?
Thanks,
CC
The reason is that the object has to be the first thing passed in to the function. This is automatically done for you if you make a method call. But $methodref->($my_obj, #args) will also work.
The CODE ref returned by can doesn’t have an object associated with it once that can is done. That’s why you still need to use an object as an invocant.
Note that this is dangerous, because there is no longer any guarantee that this is method that is supposed to be called on that object. I suppose you might do something like this:
$objmethref = $my_obj->can("methname") && sub { $my_obj->methname(#_) };
# then later
$objmethref->(#args);
but I’m not sure what it is you really want to do.
$my_obj->$methodref->(#args)
is
( $my_obj->$methodref() )->(#args)
In other words, it would call the method with no args, and attempt to use the result as a function reference. It's not what you want at all
The obvious means of calling it is
$methodref->($my_obj, #args)
but Perl provides a syntax that looks like a method-call for your pleasure.
$my_obj->$methodref(#args)
$methodref->(#args) is a function call, not a method call, so won't have the object automatically passed.
$my_obj->$methodref->(#args) would call $methodref with no parameters other than the object parameter, and use its return value as a coderef, calling that and passing it the indicated args.
In Objective-C, if I override a class method using a category, is there a way I can call the original method (the one that was overridden)?
I present you with three icky ways to do this in +(void)load. In every case, name your method MyCategory_method or so.
class_getMethodImplementation() and class_replaceMethod(). Store the old IMP, and call it directly. You need to get the method's type encoding. Note that you can just use a normal C function too...
class_getInstanceMethod(), method_getImplementation(), method_setImplementation(). As above, but you don't need to get the method's type encoding.
class_getInstanceMethod() on both methods, and then method_exchangeImplementations(). Call MyCategory_method to get the original implementation. This is the easiest way to do it.
Sometimes, it's the only reasonably easy way to make it do what you want...
EDIT: And only do this if you know what you're doing!
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCategories.html
Doesn't look like it is possible.
When a category overrides an inherited method, the method in the category can, as usual, invoke the inherited implementation via a message to super. However, if a category overrides a method that already existed in the category's class, there is no way to invoke the original implementation.
What this is saying to me is that if you override a method on a subclass via a category, you can call [super methodName] as you would normally, but if you override the base class method directly, you can't invoke the original.
If you dynamically provide the category override (see resolveInstanceMethod:), you can cache the previous method selector beforehand, and call that.