How does compiler handle missing parameter names in Objective-C? - objective-c

I have run into someone else's code that declares methods like this:
- (void) method:(id)a:(NSString*)b { }
The compiler accepts this code, giving just a warning:
'a' used as the name of the previous parameter rather than as part of the selector
The code declares various functions with this type and then invokes them through NSSelectorFromString, using the signature "methodname::". So it's all consistent.
I wonder if that method signature is just a mistake or if there's more to it. Since it's used consistently in the code, I don't think this is a typo. I don't know the author so I can't tell if this is code of a genius or the opposite.
Is 'b' an anonymous parameter? (If so, shouldn't it rather be written with a blank between the "a" and ":" to indicate this better?) I can't find anything about anon parms in the ObjC docs, though.
Will there be any change in behavior if I change the syntax to giving the second parameter a name, and fixing the signature reference accordingly? I plan to make this change to get rid of the warnings, but I wonder I might create an issue that I'm not aware of.

Everything you describe is pretty much correct. It's very bad style, but technically it's just a two-argument selector which happens to have no text before the second :. I wouldn't call b an anonymous argument since you can still give it a name, it just doesn't have any descriptive text before it as part of the selector's name.
Yes, there should probably be a space after the a.
If you want to rename it, you can use Xcode's standard Refactor->Rename functionality and just insert some text before the second :. It will update all the references and you should encounter no problems.

You can use the signature method::, even though it is not recommended by most people.
Just insert a space character before each : separating the parameters, and the compiler is happy:
- (void) method:(id)a :(NSString*)b
On page 16 "Message Syntax" of The Objective-C Programming Language
this is called an "unlabeled argument", or an "argument without keyword".
Of course you can change it to
- (void) method:(id)a withB:(NSString*)b
but this changes the selector to method:withB:.

Related

Is it OK to leave the [ and ] out for messages like at:ifAbsent: if you don't need a full block?

In Smalltalk (and specifically Pharo/Squeak) I want to know if it is OK to leave out the "[" and "]" for the argument to messages like at:ifAbsent: if you don't need a block, like this;
^ bookTitles at: bookID ifAbsent: ''.
and
^ books at: bookID ifAbsent: nil.
the code works because (in Pharo/Squeak) Object>>value just returns self. But I want to know how accepted this use is or if you should always type the [ and ] even when you don't care if the argument is evaluated quickly or more than once.
The signature:
at: key ifAbsent: aBlock
declares an intention of using a block as a 2nd parameter...
But Smalltalk is not a strongly typed language, so, what kind of objects can you pass there? any kind that understand the message #value, so, be careful about each particular meaning of #value in each case, but take advantages of polymorphism!
Not all Smalltalk dialects implement #value on Object out of the box, so your code might not run on other Smalltalk dialects, IF you hand in an object that does not understand #value.
It is okay to pass objects of whatever kind as long as you know that what #value does is what you expect,
Your code may look strange to people who come from other smalltalk dialects or are new to Smalltallk, because they learned that what you pass in here is a Block, but so does sending messages like #join: to a Collection of Strings...
In the end, I'd say don't worry if portability is not a major issue to you.
This is what Pharo’s Code Critics say about similar situations:
Non-blocks in special messages:
Checks for methods that don't use blocks in the special messages.
People new to Smalltalk might write code such as: "aBoolean ifTrue:
(self doSomething)" instead of the correct version: "aBoolean ifTrue:
[self doSomething]". Even if these pieces of code could be correct,
they cannot be optimized by the compiler.
This rule can be found in Optimization, so you could probably ignore it, but i think it is nicer anyway to use a block.
Update:
at:ifAbsent: is not triggered by this rule. And it is not optimized by the compiler. So optimization is no reason to use blocks in this case.
I would say that it is not a good idea to leave them out. The argument will be evaluated eagerly if you leave out the parens, and will be sent #value. So if "slef doSomething" has side-effects, that would be bad. It could also be bad if #value does something you don't expect e.g. the perhaps contrived
bookTitles at: bookID ifAbsent: 'Missing title' -> 'ISBN-000000'
If your code works and you are the only person to view the source, then its ok. If others are to view the source then I would say a empty block [] would have been more readable. But generally speaking if you really care about bugs its a good idea not to venture outside standard practices because there is no way to guarantee that you wont have any problem.

Runtime method to get names of argument variables?

Inside an Objective-C method, it is possible to get the selector of the method with the keyword _cmd. Does such a thing exist for the names of arguments?
For example, if I have a method declared as such:
- (void)methodWithAnArgument:(id)foo {
...
}
Is there some sort of construct that would allow me to get access to some sort of string-like representation of the variable name? That is, not the value of foo, but something that actually reflects the variable name "foo" in a local variable inside the method.
This information doesn't appear to be stored in NSInvocation or any of its related classes (NSMethodSignature, etc), so I'm not optimistic this can be done using Apple's frameworks or the runtime. I suspect it might be possible with some sort of compile-time macro, but I'm unfamiliar with C macros so I wouldn't know where to begin.
Edit to contain more information about what I'm actually trying to do.
I'm building a tool to help make working with third-party URL schemes easier. There are two sides to how I want my API to look:
As a consumer of a URL scheme, I can call a method like [twitterHandler showUserWithScreenName:#"someTwitterHandle"];
As a creator of an app with a URL scheme, I can define my URLs in a plist dictionary, whose key-value pairs look something like #"showUserWithScreenName": #"twitter://user?screenName={screenName}".
What I'm working on now is finding the best way to glue these together. The current fully-functioning implementation of showUserWithScreenName: looks something like this:
- (void)showUserWithScreenName:(NSString *)screenName {
[self performCommand:NSStringFromSelector(_cmd) withArguments:#{#"screenName": screenName}];
}
Where performCommand:withArguments: is a method that (besides some other logic) looks up the command key in the plist (in this case "showUserWithScreenName:") and evaluates the value as a template using the passed dictionary as the values to bind.
The problem I'm trying to solve: there are dozens of methods like this that look exactly the same, but just swap out the dictionary definition to contain the correct template params. In every case, the desired dictionary key is the name of the parameter. I'm trying to find a way to minimize my boilerplate.
In practice, I assume I'm going to accept that there will be some boilerplate needed, but I can probably make it ever-so-slightly cleaner thanks to NSDictionaryOfVariableBindings (thanks #CodaFi — I wasn't familiar with that macro!). For the sake of argument, I'm curious if it would be possible to completely metaprogram this using something like forwardInvocation:, which as far as I can tell would require some way to access parameter names.
You can use componentsSeparatedByString: with a : after you get the string from NSStringFromSelector(_cmd) and use your #selector's argument names to put the arguments in the correct order.
You can also take a look at this post, which is describing the method naming conventions in Objective C

Bizzare method signature, with unnamed arguments (obj-c)

I wasn't aware this syntax was valid.
+ (void) methodName:(TypeObject *)typeObject1:(TypeObject *)typeObject2;
Which is then called like so:
[object methodName:obj1:obj2];
I find it ugly and disturbing, but it builds.
Can someone point me at a reference which explains why this is valid.
FWIW the codebase (inherited) that this comes from, is rife with sloppy, lazy stuff, dozens of spelling errors and looks like it was formatted by someone with no need to ever read it again. (Thank you again uncrustify.)
This is a well-kown and documented feature (pdf, p. 14)
In principle, a Rectangle class could instead implement a setOrigin::
method with no label for the second parameter, which would be invoked
as follows:
[myRectangle setOrigin:30.0 :50.0]; // This is a bad example of multiple parameters
but apple discourage everbody of using parameter passing without keyword:
Use keywords before all arguments.
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag; -> Right.
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; -> Wrong.
Why it was allowed by the creators of objective-C, I dont know. Maybe it has to do with the Smalltalk heritage.

Correct Form for naming method parameters that clash with property names

If I have a class with a property of notificationCenter, and implement a method with this signature:
-(void)doSomethingWithNotificationCenter:(NSNotificationCenter *)notificationCenter
Xcode rightly gives me an error:
'local declaration of notificationCenter hides instance variable'
So in Objective C is there a convention for naming this parameter to avoid this collision?
The parameter should be called aNotificationCenter or possibly aCenter.
This seems like a personal preference, I have seen aNotificationCenter as mentioned above, inNotificationCenter, theNotificationCenter among others. I think as long as you are consistent in your own code any basic, readable choice is OK.
PS - my personal preference is inNotificationCenter.
I sometimes use the format receivedNotificationCenter or notificationCenterParam.

Write a compiler for a language that looks ahead and multiple files?

In my language I can use a class variable in my method when the definition appears below the method. It can also call methods below my method and etc. There are no 'headers'. Take this C# example.
class A
{
public void callMethods() { print(); B b; b.notYetSeen();
public void print() { Console.Write("v = {0}", v); }
int v=9;
}
class B
{
public void notYetSeen() { Console.Write("notYetSeen()\n"); }
}
How should I compile that? what i was thinking is:
pass1: convert everything to an AST
pass2: go through all classes and build a list of define classes/variable/etc
pass3: go through code and check if there's any errors such as undefined variable, wrong use etc and create my output
But it seems like for this to work I have to do pass 1 and 2 for ALL files before doing pass3. Also it feels like a lot of work to do until I find a syntax error (other than the obvious that can be done at parse time such as forgetting to close a brace or writing 0xLETTERS instead of a hex value). My gut says there is some other way.
Note: I am using bison/flex to generate my compiler.
My understanding of languages that handle forward references is that they typically just use the first pass to build a list of valid names. Something along the lines of just putting an entry in a table (without filling out the definition) so you have something to point to later when you do your real pass to generate the definitions.
If you try to actually build full definitions as you go, you would end up having to rescan repatedly, each time saving any references to undefined things until the next pass. Even that would fail if there are circular references.
I would go through on pass one and collect all of your class/method/field names and types, ignoring the method bodies. Then in pass two check the method bodies only.
I don't know that there can be any other way than traversing all the files in the source.
I think that you can get it down to two passes - on the first pass, build the AST and whenever you find a variable name, add it to a list that contains that blocks' symbols (it would probably be useful to add that list to the corresponding scope in the tree). Step two is to linearly traverse the tree and make sure that each symbol used references a symbol in that scope or a scope above it.
My description is oversimplified but the basic answer is -- lookahead requires at least two passes.
The usual approach is to save B as "unknown". It's probably some kind of type (because of the place where you encountered it). So you can just reserve the memory (a pointer) for it even though you have no idea what it really is.
For the method call, you can't do much. In a dynamic language, you'd just save the name of the method somewhere and check whether it exists at runtime. In a static language, you can save it in under "unknown methods" somewhere in your compiler along with the unknown type B. Since method calls eventually translate to a memory address, you can again reserve the memory.
Then, when you encounter B and the method, you can clear up your unknowns. Since you know a bit about them, you can say whether they behave like they should or if the first usage is now a syntax error.
So you don't have to read all files twice but it surely makes things more simple.
Alternatively, you can generate these header files as you encounter the sources and save them somewhere where you can find them again. This way, you can speed up the compilation (since you won't have to consider unchanged files in the next compilation run).
Lastly, if you write a new language, you shouldn't use bison and flex anymore. There are much better tools by now. ANTLR, for example, can produce a parser that can recover after an error, so you can still parse the whole file. Or check this Wikipedia article for more options.