Projects
Home     Blog     Install     New Ticket     View Tickets     Browse Source

Ticket #112 (new defect)

Opened 3 months ago

Last modified 3 months ago

NSNumber should behave consistently regardless of how it is accessed

Reported by: jordan.breeding@… Owned by: lsansonetti@…
Priority: blocker Milestone: MacRuby 0.4
Component: MacRuby Keywords:
Cc:

Description

Currently if an NSNumber is stored in something (like an NSDictionary) it behaves differently depending on how you access it. Accessing it through Cocoa methods gets you a raw NSCFNumber which doesn't work with ruby methods, accessing it through [] gets you a ruby object that works.

6 jordan@thetourist ~/Desktop/Scripts > macirb
>> framework("Cocoa")
=> true
>> myDict = NSMutableDictionary.dictionary
=> {}
>> NSNumber.numberWithInt(100)
=> #<NSCFNumber:0x1020fc0>
>> myDict.setObject(100, forKey: "testNum1")
=> nil
>> myDict.setObject(NSNumber.numberWithInt(100), forKey: "testNum2")
=> nil
>> myDict.objectForKey("testNum1")
=> 100
>> myDict.objectForKey("testNum2")
=> #<NSCFNumber:0x10aaca0>
>> myDict.objectForKey("testNum1").to_f
=> 100.0
>> myDict.objectForKey("testNum2").to_f
NoMethodError: undefined method `to_f' for #<NSCFNumber:0x10aaca0>
	from (irb):9
	from /usr/local/bin/macirb:12:in `<main>'
>> myDict.objectForKey("testNum1") / 50
=> 2
>> myDict.objectForKey("testNum2") / 50
NoMethodError: undefined method `/' for #<NSCFNumber:0x10aaca0>
	from (irb):11
	from /usr/local/bin/macirb:12:in `<main>'
>> myDict["testNum1"].to_f
=> 100.0
>> myDict["testNum2"].to_f
=> 100.0
>> myDict["testNum1"] / 50
=> 2
>> myDict["testNum2"] / 50
=> 2
>>

Change History

Changed 3 months ago by lsansonetti@…

  • milestone set to MacRuby 0.4

The problem here is that NSNumber does not implement the Numeric interface yet, because it's defined on Numeric itself.

$ macirb
>> 1.class.ancestors
=> [Fixnum, Precision, Integer, Precision, Numeric, Comparable, NSNumber, NSValue, NSObject, Kernel]
>> NSNumber.numberWithInt(42).class.ancestors
=> [NSCFNumber, NSNumber, NSValue, NSObject, Kernel]
>> NSNumber.numberWithInt(42) + 1
NoMethodError: undefined method `+' for #<NSCFNumber:0x13a49b0>
	from (irb):3
	from /usr/local/bin/macirb:12:in `<main>'

Ideally we should reimplement Numeric on top of NSNumber as we did for String/Array/Hash and change MacRuby to always emit NSNumbers (or subclasses) for fixnums instead of special constants.

Changed 3 months ago by jordan.breeding@…

Yeah I was kind of thinking that it would be nice for Ruby numbers to be based on NSNumber like Strings and Hashes as well.

Note: See TracTickets for help on using tickets.