Reputation: 41
I am having issues with the following code:
private enum Op : Printable {
case Operand(Double)
case Constant(String, Double)
case Variable(String)
case UnaryOperation(String, Double -> Double)
case BinaryOperation(String, (Double, Double) -> Double)
var description: String {
get {
switch self {
case .Operand(let operand):
return "\(operand)"
case .Constant(let constant, _):
return constant
case .Variable(let variable):
return variable
case .UnaryOperation(let symbol, _):
return symbol
case .BinaryOperation(let symbol, _):
return symbol
}
}
}
}
private var knownOps = [String:Op]()
init() {
func learnOp(op: Op) {
knownOps[op.description] = op
}
learnOp(Op.Constant("π", M_PI))
learnOp(Op.UnaryOperation("√", sqrt))
learnOp(Op.UnaryOperation("sin", sin))
learnOp(Op.UnaryOperation("cos", cos))
learnOp(Op.UnaryOperation("±") { -1 * $0 })
learnOp(Op.BinaryOperation("×", *))
learnOp(Op.BinaryOperation("÷") { $1 / $0 })
learnOp(Op.BinaryOperation("+", +))
learnOp(Op.BinaryOperation("-") { $1 - $0 })
}
After the init() is complete, the dictionary knownOps
contains the following:
knownOps [String : Calculator.CalculatorModel.Op] 9 key/value pairs
[0] _DictionaryElement<String, Calculator.CalculatorModel.Op>
key String "×"
value Calculator.CalculatorModel.Op Operand Operand
[1] _DictionaryElement<String, Calculator.CalculatorModel.Op>
key String "+"
value Calculator.CalculatorModel.Op Operand Operand
[2] _DictionaryElement<String, Calculator.CalculatorModel.Op>
key String "÷"
value Calculator.CalculatorModel.Op Operand Operand
[3] _DictionaryElement<String, Calculator.CalculatorModel.Op>
key String "π"
value Calculator.CalculatorModel.Op Constant Constant
[4] _DictionaryElement<String, Calculator.CalculatorModel.Op>
key String "-"
value Calculator.CalculatorModel.Op Operand Operand
[5] _DictionaryElement<String, Calculator.CalculatorModel.Op>
key String "±"
value Calculator.CalculatorModel.Op UnaryOperation UnaryOperation
[6] _DictionaryElement<String, Calculator.CalculatorModel.Op>
key String "sin"
value Calculator.CalculatorModel.Op UnaryOperation UnaryOperation
[7] _DictionaryElement<String, Calculator.CalculatorModel.Op>
key String "√"
value Calculator.CalculatorModel.Op UnaryOperation UnaryOperation
[8] _DictionaryElement<String, Calculator.CalculatorModel.Op>
key String "cos"
value Calculator.CalculatorModel.Op UnaryOperation UnaryOperation
My question is: why are the binaryOperation
s being captured as Operand
s in the dictionary?
Upvotes: 4
Views: 716
Reputation: 10136
Ok, I think I managed to reproduce what you say in your question. If I run the thing in debug mode in Xcode 6.4, put a breakpoint, and inspect the contents of knownOps
, then indeed I see binary operations stored as just an operand.
What I think is happening is Swift compiler optimisation coupled with a bug.
Reasons I think so are:
enum
in knownOps
as Invalid
.knownOps
by printing them out (e.g. in a for-loop) then everything is printed out just as expected, both in Xcode 6.4 and in Xcode 7 beta.knownOps
by stepping into instructions, then I do not see anything that looks like: 1) check out the value stored by enum
property, and then 2) based on property's value, decide what to return as description
computed property of the enum
.Therefore, most likely your code is simple enough for the compiler to be able to "predict" what has to be printed out or what the execution path should look like, to just throw all "unnecessary" stuff out. And probably the debugger in 6.4 is simply not up to speed with this thing..
But good news is that debugger from Xcode 7 "knows" about this. It says invalid
instead of feeding you with a bogus.
Upvotes: 1
Reputation: 1235
I added the following variable to your enum:
var type: String {
get {
switch self {
case .Operand:
return "Operand"
case .Constant:
return "Constant"
case .Variable:
return "Variable"
case .UnaryOperation:
return "UnaryOperation"
case .BinaryOperation:
return "BinaryOperation"
}
}
}
Then looped through the dict with the following code:
for (key, value) in knownOps
{
let valueType = value.type
println("\(key) : \(valueType)")
}
This gave me the output:
× : BinaryOperation
+ : BinaryOperation
÷ : BinaryOperation
π : Constant
- : BinaryOperation
± : UniaryOperation
sin : UniaryOperation
√ : UniaryOperation
cos : UniaryOperation
So I guess the answer to your questions is that it isn't. I can't offer an answer as to why the debugger or whatever you used to inspect the values was incorrect, but the code you posted isn't wrong.
Upvotes: 1