For Xcode 6.1 one of the update point is:
Swift REPL built into the Xcode debugger can inspect and manipulate
your running app
I've created empty project, set a breakpoint in viewDidLoad, when app stops at breakpoint, I'm typing 'repl' in Xcode console, then trying to print self with
println(self)
But Xcode gives me the error:
error: use of unresolved identifier 'self'
But it's not working.
The question is: What I'm doing wrong?
Turns out there are actually two expression evaluators for Swift in lldb, the repl
and the regular expression
command. The two differ in important ways.
The repl
command evaluates code as the regular swift compiler would if entered in a new Swift module file that is imported into the currently running app. Actually, to be more accurate, each successive invocation of repl
adds code to such a module, and the repl adds some powerful features like being able to redefine classes which the Swift compiler doesn't allow. So it is most useful for defining whole new classes, functions, etc. Having the repl
use this global context is also necessary because some definitions in Swift can only be performed at the module level, and repl
gives you access to all these features of the language. OTOH, this means pretty much by definition the repl
command has no visibility into the context in which you are running the repl
command.
The expression
command evaluates code as though it were running in the context of the function you are currently stopped in. This is useful because it gives you access to ivars and local variables, and really acts like code that might be in that particular context. But a side effect of performing that trick is that it can't be exactly like making a new module - which is what repl
is supposed to emulate. Note, the things that you can't do in expr
are fairly esoteric, and you can often get away with building scratch classes and the like in the expression
command. You want to use expr
to run your println(self)
command.
In short, if you want to cook up new classes, etc, while debugging, use the repl
command, but if you want to access local variables, etc, use expr
.
Note to make things slightly more confusing, repl
is actually a flavor or expr
. If you look at the lldb help for repl it will tell you the command is an alias for expression -r --
. Some folks also use another alias: print
, which is expression --
. That alias is just handy for turning off option parsing when entering your real expression into the command...