ObjC - Problems with using an NSLog replacement? - objective-c

Being relatively new to programming--think Programming in Objective-C by Kochan, Chapter 15--I'm wondering if there's a reason why it's a bad idea--especially for a new programmer?--to use an NSLog replacement such as the following:
#define MGLog(format, ...) CFShow([NSString stringWithFormat:\
format, ## __VA_ARGS__])
and then call it as follows:
MGLog(#"Yo' mama wears combat boots.");
It's much cleaner to use this for learning how to manage strings, building a rolodex program, like he's got me doing, but I don't want to get into the habit of doing it this way if there are drawbacks. Thanks for any help, guys & gals.
BTW, if it matters, I'm using XCode 4.

Well, there is ABSOLUTELY no problem with that.
The purpose of log functions is to provide you with as much (useful) information as possible.
If you think that using THIS version of NSLog for debugging is more helpful to you, then how could it be wrong?
Note : The more involved you become with Objective-C/Cocoa program, the more likely it is that you'll set to one or the other log function (perhaps, one you'll write yourself to suit your particular needs).
Here's the one I'm mostly using :
#define _LOG(prefixch, fmt, ...) \
NSLog((NSString*)(CFSTR("%c [%s:%d] " fmt)), prefixch, \
__SRC_FILENAME__, __LINE__, ##__VA_ARGS__)
It shows the FILE we're in, the LINE we're at and anything else I might need...

Related

Drop use of = in parsing arguments in raku

The fact that you can write in raku the following
unit sub MAIN(Int $j = 2);
say $j
is amazing, and the fact that the argument parsing is done for you is beyond
useful. However I find personally extremely unergonomic
that for such arguments you habe to write a = to set the value, i.e.
./script.raku -j=5
I was wondering if there is a way to tell the parser that it should allow options without
the = so that I can write
./script.raku -j 5
I haven't seen this in the docs and this would really be much more intuitive for some people
like me. If it is not currently possible, I think it would be a useful add-on.
You could also use SuperMAIN, a library for CLI processing. This add some new superpowers to MAIN
There has been a lot of discussion of how command line parameters should be parsed. At the moment there are no plans of adding more functionality to what Raku provides out of the box.
If you want more tweakability, you should probably look at the Getopt::Long module by Leon Timmermans

Dollar and exclamation mark (bang) symbols in VTL

I've recently encountered these two variables in some Velocity code:
$!variable1
!$variable2
I was surprised by the similarity of these so I became suspicious about the correctness of the code and become interested in finding the difference between two.
Is it possible that velocity allows any order of these two symbols or do they have different purpose? Do you know the answer?
#Jr. Here is the guide I followed when doing VM R&D: http://velocity.apache.org/engine/1.7/user-guide.html
Velocity uses the !$ and $! annotations for different things. If you use !$ it will basically be the same as a normal "!" operator, but the $! is used as a basic check to see if the variable is blank and if so it prints it out as an empty string. If your variable is empty or null and you don't use the $! annotation it will print the actual variable name as a string.
I googled and stackoverflowed a lot before I finally found the answer at people.apache.org.
According to that:
It is very easy to confuse the quiet reference notation with the
boolean not-Operator. Using the not-Operator, you use !${foo}, while
the quiet reference notation is $!{foo}. And yes, you will end up
sometimes with !$!{foo}...
Easy after all, shame it didn't struck me immediately. Hope this helps someone.

Is it possible to parse a mathematical expression by using #define?

I want to make a scientific calculator in which the user enters something like 3+4*(3-5)/23 and then the calculator can return the value.
Now I'm trying to find a way to parse a string of mathematical expression. I know that there are some built parsers and algorithms but I want to know whether it's possible by using #define method.
Basically, I want to use the #define to literally remove the # and " " in a string and make it look like an expression that can be evaluated. At this stage, I won't use unknown variables like x or 3*k or a*b/c. All will be numbers and operators like 3+4 and 32 that can be directly evaluated by the compiler. Here is what I want to write in #define:
#define eval#"(x)" x
In the above code, eval is just a signal of parsing and the #"x" is the actual string that need to parse and x is a mathematical expression. After the translation, only x will remain. For example, if I write
double result = eval#"(3+4)";
the compiler will read
double result = 3+4;
(according to my understanding of #define). However, the code does not work. I suspect that the quotation marks confuse the compiler and cause the code to break. So my question is: can anyone come up with a solution using #define?
This is not possible with the preprocessor, no string manipulation besides concatenation supported.
Why would you need the #"x" syntax anyways? You can just put the expression right there in the code.
People are right, you cannot do it in direct way, however if you very want macro:
#define eval(x) [[[NSExpression expressionWithFormat:x] expressionValueWithObject:nil context:nil] doubleValue]
double result = eval(#"3+4");
#define is an invocation of the C preprocessor, which is not capable of this kind of manipulation. It almost sounds like you're trying to define an Objective-C macro that would do the same kind of thing as a LISP macro, but that's not possible. Why don't you tell us what the original problem is that you're trying to solve... I think we can probably come up with an easier way to do what you're trying to do.

obfuscated way to get "0" in a tcl function, cross platform?

I haven't used tcl before and just need to do one trick, I can do it trivially in something like bash but I need it to work cross-platform (e.g. tcl in cygwin on windows).
Can someone suggest a short (5-10) obfuscated function that just returns 0 after taking two string args? It just can't do something like run shell commands that won't work under Mac/Cygwin.
fwiw, why do this: buying some time in writing a test- the thing generating one of the files is broken but I can't change it, making a hack in the TCL test script until I make extensive changes to use a different 'test core' that isn't broken. For now just declare the first file as 'good' if it exists.
I don't understand the requirement for obfuscation, but the simplest way to create a command that takes two arguments and returns 0 is this:
proc theCommandName {firstArgument secondArgument} {
return 0
}
There are all sorts of ways of making things obscure (e.g., a regular expression that doesn't actually match anything, a complicated expression) but as I said before, I don't understand the requirement in that area; I always try to make my code be the simplest thing that could possibly work…

How would I write the following rb-appscript in objc-appscript?

The documentation in the appscript objc-trunk randomly uses ruby in the section called "Performance Issues".
require "appscript"
include Appscript
desiredEmail = 'sam.brown#foo.com'
p app('Address Book').people[
its.emails.value.contains(desiredEmail)
].name.get
How would this be written in Objective-C? I apologize if this seems like an overly basic question, I have 0 experience with Ruby.
Thanks.
If you run the ruby script and use ASTranslate it should translate the raw appscript commands to Objc-appscript.
Edit01:
I think it will look something like this. I haven't run the tool to make the glue code so I'm guessing about the way the app name shows up.
#import "AddressBookGlue.h" //Dont know the precise name
AddressBookApplication *abApp=[[AddressBookApplication alloc] initWithName: #"Address Book.app"];
NSString *desiredEmail=#"sam.brown#foo.com"
NSString *returnedName= [[[[[[abApp people] emails] value] contains:desiredEmail] name] get];
Basically, it follows the same rules that Objectic-c uses when converting from a dot syntax: anywhere there is a dot in the original syntax, expect a bracket in Objective-C.
I might add that if you're going to be doing a lot of this type scripting, it would be best to spend a day or two learning the basics of ruby or python. It's a lot easier to work with OSA in a dot syntax than a nested syntax. Just looking at all those brackets in the documentation for Objc-appscript makes my eyes water.
Apologies for the incompleteness of the objc-appscript manual, which was originally ported from rb-appscript as you can tell. (FWIW, I should have some time to work on appscript this spring.)
Translating the Ruby code back to AppleScript first is probably the easiest approach:
tell application "Address Book"
get name of every person where value of its email contains "hengist.podd#virgin.net"
end tell
Running it through ASTranslate gives this:
#import "ABGlue/ABGlue.h"
ABApplication *addressBook = [ABApplication applicationWithName: #"Address Book"];
ABReference *ref = [[[addressBook people] byTest: [[[ABIts emails] value] contains: #"hengist.podd#virgin.net"]] name];
id result = [ref getItem];
From what I understand, that's printing the name of every person who has an email of "sam.brown#foo.com".
There's no direct correlation for how to do this in Cocoa. Fortunately for you, Address Book is scriptable, which means you can use the Scripting Bridge framework to interact with it from a Cocoa app.
This page has a really great explanation on how to simply interact with Mail.app via ScriptingBridge: http://robnapier.net/blog/scripting-bridge-265
Hopefully that should give you enough information to get going in the right direction.