Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interactivly play with objects in the Xcode lldb swift repl?

Tags:

xcode

swift

lldb

Lets say I have a small program that involves picking a document from a database:

let errorDatabase
= NSError(domain: "dk.myproject.couchbase", code: 0, userInfo: nil)

let rev = database.existingDocumentWithID("_design/" + designDocName)
// in xcode I set a break point here
assert(rev != nil)
if rev == nil {
    promise.failure(errorDatabase)
}

Then I insert a breakpoint, run the program and can afterwards do:

(lldb) po rev
0x00007fad21df61c0
 {
  ObjectiveC.NSObject = {...}
}
(lldb) print rev.properties["views"]
(AnyObject?) $R29 = Some {
...

Perfect lets enter the repl and play with the rev object:

(lldb) repl
6> rev
repl.swift:6:1: error: use of unresolved identifier 'rev'
rev
^

I might have wrong expectations for the swift repl - I'm expecting some kind of python, nodejs or scala repl. behaviour where I can play around with objects etc.

Any hints?

like image 916
pellekrogholt Avatar asked May 16 '15 16:05

pellekrogholt


2 Answers

I was hoping the same thing the first time I typed repl within LLDB, but I soon discovered that unfortunately you can't do it.

The repl inside LLDB, it turns out, is running in a module injected at top level. Thus you could, from within the repl here, define top-level objects and functions, which are then visible back in "normal" lldb:

(lldb) repl
1> func pt() -> CGPoint {
2. return CGPointZero
3. }
4> :
(lldb) po pt()
(0.0, 0.0)

... but the converse is not true: you cannot, inside the repl, see local variables at the point you are paused, as they are obviously not in scope from top level.

Do note, however, that you can perform assignments in an expr expression. Thus, you can change the value of a local variable, the properties of an existing object, etc., just by saying expr followed by an assignment - and that this does take place in the context where you are paused.

For example, let's say I'm in the middle of creating a pan edge gesture recognizer, and I pause at a breakpoint at this line:

p.edges = UIRectEdge.Right

Now:

(lldb) th step-over
(lldb) expr p.edges = UIRectEdge.Left
(lldb) continue

And now the app is running, but the gesture recognizer works when swiping from the left instead of the right.

like image 104
matt Avatar answered Oct 22 '22 11:10

matt


Note, I described the purposes and differences between "expression" and "repl" in this question:

Xcode 6.1 'Swift REPL built into the Xcode debugger can inspect and manipulate your running app' not working

Maybe that will help you understand the similarities & differences you are seeing and then intent behind them.

like image 2
Jim Ingham Avatar answered Oct 22 '22 11:10

Jim Ingham