Smalltalk and ruby - 2012-12-08

1,888 views

Published on

An Amateur Smalltalk User’s Observations on Ruby Object Model and Bytecode

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,888
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
16
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Smalltalk and ruby - 2012-12-08

  1. 1. An Amateur Smalltalk User’s Observations on Ruby Object Model and Bytecode “freedom” Koan-Sin Tan freedom_at_computer.org RubyConf Taiwan, Dec 8th, 2012 1Friday, March 22, 13
  2. 2. Or say, learning Ruby, a stupid way 2Friday, March 22, 13
  3. 3. Outline • General introduction • Smalltalk-80 and Ruby object models • Smalltalk-80 and Ruby bytecode 3Friday, March 22, 13
  4. 4. Who am I • Learnt to write program on MPF-II • Used to be a programming language junkie • Learnt a bit Smalltalk during early 90s, use it on and off • Recent interest in ST-80 because of Scratch and BYOB/SNAP • Working on dealing with big.LITTLE system • Knew little about Ruby 4Friday, March 22, 13
  5. 5. MPF-II • Multi-tech Micro-Professor II, MPF-II • A not so compatible Apple-][ clone • 6502 • Basic similar to Apple SOFT • Different monitor • I got one of this in 1983 5Friday, March 22, 13
  6. 6. the first smalltalk-80 I used is on Sun’s SunView, image from Wikipedia 6Friday, March 22, 13
  7. 7. Smalltalk/V 286, from http://www.drdobbs.com/ architecture-and-design/making-smalltalk-with-widgets/ 184408550 7Friday, March 22, 13
  8. 8. Scratch and BYOB/SNAP visual programming 8Friday, March 22, 13
  9. 9. ARM big.LITTLE 9Friday, March 22, 13
  10. 10. 10Friday, March 22, 13
  11. 11. What I knew about Ruby • freebsd: portupgrade is written in ruby, http:// wiki.freebsd.org/portupgrade • RoR • message passing • temporary variable, block, block arguments • However, a block in ruby is not an object!! • And of course, ruby is more than smalltalk-80 11Friday, March 22, 13
  12. 12. Smalltalk-80 • Object-Oriented • Design Pattern: Programming • if you read GoF • OO GUI environment, book, you ran into IDE lots Smalltalk patterns before • VM, bytecode • Learning/educational • Lambda, functional language, block • Logo and the dream of Dynabook • Message passing 12Friday, March 22, 13
  13. 13. some smalltalk-80 systems • Squeak:  originally  from  Alan  Kay  and  other   veteran  Smalltalk  guys • Pharo:  a  Squeak  fork  focusing  on  providing  a   clean  and  ready-­‐to-­‐use  smalltalk   environment • VisualWorks:  the  ParcPlace  system • GNU  Smalltalk 13Friday, March 22, 13
  14. 14. Object Model • Object Model can be used to refer to different things • We just touch what a common language user is aware of, not something like the details of how objects are represented in VMs • I believe you can get more about VM implementations from Sasada-San’s talk 14Friday, March 22, 13
  15. 15. Smalltalk Object Model • From "purple book", Chap 16 1. Every class is ultimately a subclass of class Object, except for Object itself, which has no superclass. In particular, Class is a subclass of ClassDescription, which is a subclass of Behavior which is a subclass of Object 2. Every object is an instance of a class 3. Every class is an instance of a metaclass 4. All metaclasses are subclasses of Class 5. Every metaclass is an instance of Metaclass 6. The method of Class and it superclasses support the behavior common to all objects that are classes 7. The methods of instances of Metaclass add the behavior specific to particular classes 15Friday, March 22, 13
  16. 16. Smalltalk Object Model •10 factorial --> 3628800 •10 factorial class --> SmallInteger •SmallInteger superclass --> Integer •Integer  superclass  --> Number •Number  superclass  --> Magnitude •Magnitude  superclass  --> Object •Object  superclass  -­‐-­‐>  ProtoObject •ProtoObject  superclass  -­‐-­‐>  nil 16Friday, March 22, 13
  17. 17. • 10 factorial class allSuperClasses --> an OrderedCollection(Integer Number Magnitude Object ProtoObject) 17Friday, March 22, 13
  18. 18. • SmallInteger class --> SmallInteger class • Integer  class  --> Integer  class • Number  class -->  Number  class • Magnitude  class -->  Magnitude  class • Object  class -->  Object  class • ProtoObject  class -->  ProtoObject  class 18Friday, March 22, 13
  19. 19. ProtoObject ProtoObject class Object Object class Magnitude Magnitude class Number Number class Integer Integer class SmallInteger SmallInteger class 10 Key instance-of figures modified from “Pharo by Example” 19Friday, March 22, 13
  20. 20. 4. All metaclasses are subclasses of Class 5. Every metaclass is an instance of Metaclass 20Friday, March 22, 13
  21. 21. SmallInteger class superclass --> Integer class Integer class superclass --> Number class umber class superclass --> Magnitude class Magnitude class superclass --> Object class Object class superclass --> ProtoObject class ProtoObject class superclass --> Class Class class class --> Metaclass 21Friday, March 22, 13
  22. 22. Class class Class ProtoObject ProtoObject class Metaclass class Object Object class Magnitude Magnitude class Metaclass Number Number class Integer Integer class SmallInteger SmallInteger class Key instance-of 10 22Friday, March 22, 13
  23. 23. 6. The method of Class and it superclasses support the behavior common to all objects that are classes 7. The methods of instances of Metaclass add the behavior specific to particular classes 23Friday, March 22, 13
  24. 24. Class class class --> Metaclass Metaclass superclass --> ClassDescription. ClassDescription superclass --> Behavior Behavior superclass --> Object Class class superclass --> ClassDescription class ClassDescription class --> superclass Behavior class Behavior class superclass --> Object class 24Friday, March 22, 13
  25. 25. Behavior class Behavior ClassDescription class ClassDescription Class class Class ProtoObject ProtoObject class Metaclass class Object Object class Magnitude Metaclass Magnitude class Number Number class Integer Integer class Key SmallInteger instance-of SmallInteger class 10 25Friday, March 22, 13
  26. 26. from “PBE” 26Friday, March 22, 13
  27. 27. • since I cannot find good Ruby tutorial/book similar to blue/purple book, let see check if we can use similar way to explore ruby 27Friday, March 22, 13
  28. 28. Ruby Metaclass • Singleton class, eigenclass 28Friday, March 22, 13
  29. 29. from ‘ri Class’ of ruby 1.8 +------------------+ | | Object---->(Object) | ^ ^ ^ ^ | | | | | | | | +-----+ +---------+ | | | | | | | +-----------+ | | | | | | | +------+ | Module--->(Module) | | | ^ ^ | OtherClass-->(OtherClass) | | | | | | Class---->(Class) | ^ | | | 29 +----------------+Friday, March 22, 13
  30. 30. from ‘ri Class’ of ruby 1.9 • All  metaclasses  are  instances  of  the  class  `Class.           +---------+ +-... | | | BasicObject-----|-->(BasicObject)-------|-... ^ | ^ | | | | | Object---------|----->(Object)---------|-... ^ | ^ | | | | | +-------+ | +--------+ | | | | | | | | Module-|---------|--->(Module)-|-... | ^ | | ^ | | | | | | | | Class-|---------|---->(Class)-|-... | ^ | | ^ | | +---+ | +----+ | | obj--->OtherClass---------->(OtherClass)-----------... 30Friday, March 22, 13
  31. 31. Ruby Eigenclass hierarchy noway:work freedom$ ruby -v freedom@freedom-desktop:~$ ruby -v ruby 1.9.3p0 (2011-10-30 revision 33570) [arm-linux- ruby 1.8.7 (2012-02-08 patchlevel 358) eabi] [universal-darwin12.0] freedom@freedom-desktop:~$ irb -v irb 0.9.6(09/06/30) noway:work freedom$ irb -v freedom@freedom-desktop:~$ irb irb(main):001:0> 1.class irb 0.9.5(05/04/13) => Fixnum irb(main):002:0> 1.class.class noway:work freedom$ irb => Class irb(main):003:0> 1.class.class.superclass >> 1.class => Module irb(main):004:0> 1.class.class.superclass.superclass => Fixnum => Object irb(main):005:0> >> 1.class.class 1.class.class.superclass.superclass.superclass => BasicObject => Class irb(main):006:0> 1.class.class.superclass.superclass.superclass.supercl >> 1.class.class.superclass ass => nil => Module irb(main):007:0> >> 1.class.class.superclass.superclass => Object >> 1.class.class.superclass.superclass.superclass => nil >> 31Friday, March 22, 13
  32. 32. >> 1.class.ancestors => [Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel] 32Friday, March 22, 13
  33. 33. $ rbenv exec irb meta.rb rb(main):001:0> 1.class.class => Class irb(main):002:0> 1.class.class.ancestors => [Class, Module, Object, Kernel, BasicObject] $rbenv exec irb meta.rb meta.rb(main):001:0> class Object meta.rb(main):002:1> def metaclass meta.rb(main):003:2> class << self; self; end meta.rb(main):004:2> end meta.rb(main):005:1> end => nil meta.rb(main):006:0> meta.rb(main):007:0* 1.class.metaclass => #<Class:Fixnum> eta.rb(main):008:0> 1.class.metaclass.superclass => #<Class:Integer> meta.rb(main):009:0> 1.class.metaclass.ancestors => [Class, Module, Object, Kernel, BasicObject] 33Friday, March 22, 13
  34. 34. meta.rb(main):009:0> 1.class.metaclass.ancestors => [Class, Module, Object, Kernel, BasicObject] • hmm..., back to superclass meta.rb(main):010:0> 1.class.metaclass.superclass.superclass => #<Class:Numeric> meta.rb(main):011:0> 1.class.metaclass.superclass.superclass.superclass => #<Class:Object> meta.rb(main):012:0> 1.class.metaclass.superclass.superclass.superclass.superclass => #<Class:BasicObject> meta.rb(main):013:0> 1.class.metaclass.superclass.superclass.superclass.superclass.superclass => Class 34Friday, March 22, 13
  35. 35. Rubys Object Hierarchy 2 Basic instance ! != == __id__ __send__ equal? Object methods instance_eval instance_exec !~ <=> === =~ class clone super define_singleton_method display dup eigen_class class eigen_methods enum_for eql? extend freeze frozen? hash initialize_clone initialize_dup inspect instance_of? instance_variable_defined? instance_variable_get instance_variable_set included instance instance_variables is_a? kind_of? method Kernel Object methods methods nil? object_id private_methods modules protected_methods public_method public_methods public_send respond_to? respond_to_missing? send singleton_class singleton_methods taint tainted? tap to_enum to_s trust untaint untrust untrusted? super class < <= > >= ancestors autoload autoload? class_eval class_exec class_variable_defined? class_variable_get class_variable_set Module class_variables const_defined? const_get instance const_missing const_set constants include? methods included_modules instance_method instance_methods method_defined? module_eval module_exec name private_class_method private_constant private_instance_methods private_method_defined? super protected_instance_methods protected_method_defined? public_class_method class public_constant public_instance_method public_instance_methods public_method_defined? remove_class_variable Class instance •So Ruby’s object hierarchy methods allocate new superclass super methods class should be similar to this Basic Object eigen class #<Class: BasicObject> instance methods •http://drtom.schank.ch/posts/ super class methods super class 2011/12/11/ Object eigen class #<Class:Object> instance methods Rubys_Object_Model_and_Eige super class methods super class nclasses/ instance try_convert eigen String class #<Class:String> methods Thomas Schank © 2011 (CC BY-ND) 35Friday, March 22, 13
  36. 36. Bytecode • Bytecode is not new at all • Smalltalk is one of early bytecode users • Smalltalk bytecode • end of Chapter 26, http:// www.mirandabanda.org/bluebook/ bluebook_chapter26.html#TheBytecodes26 • Chap. 28, http://www.mirandabanda.org/ bluebook/bluebook_chapter28.html 36Friday, March 22, 13
  37. 37. Smalltalk bytecode categories • pushes • indicates  the  source  of  an  object  to  be  added  to  the  top  of  the   interpreters  stack • stores • indicates  the  variable  whose  value  should  be  changed • sends • specifies  the  selector  of  a  message  to  be  sent  and  how  many   arguments  it  should  have. • returns •  a  value  is  returned  for  the  message  that  invoked  that   CompiledMethod • and  jumps • you  know  what  these  are 37Friday, March 22, 13
  38. 38. Smalltalk  bytecodes Range Bits FuncQon 0-­‐15 0000iiii Push  Receiver  Variable  #iiii 16-­‐31 0001iiii Push  Temporary  LocaQon  #iiii 32-­‐63 001iiiii Push  Literal  Constant  #iiiii 64-­‐95 010iiiii Push  Literal  Variable  #iiiii 96-­‐103 01100iii Pop  and  Store  Receiver  Variable  #iii 104-­‐111 01101iii Pop  and  Store  Temporary  LocaQon  #iii 112-­‐119 01110iii Push  (receiver,  true,  false,  nil,  -­‐1,  0,  1,  2)  [iii] 120-­‐123 011110ii Return  (receiver,  true,  false,  nil)  [ii]  From  Message 124-­‐125 0111110i Return  Stack  Top  From  (Message,  Block)  [i] 126-­‐127 0111111i unused 128 10000000  jjkkkkkk Push  (Receiver  Variable,  Temporary  LocaQon,  Literal  Constant,  Literal  Variable)  [jj]  #kkkkkk 129 10000001  jjkkkkkk Store  (Receiver  Variable,  Temporary  LocaQon,  Illegal,  Literal  Variable)  [jj]  #kkkkkk 130 10000010  jjkkkkkk Pop  and  Store  (Receiver  Variable,  Temporary  LocaQon,  Illegal,  Literal  Variable)  [jj]  #kkkkkk 131 10000011  jjjkkkkk Send  Literal  Selector  #kkkkk  With  jjj  Arguments 132 10000100  jjjjjjjj  kkkkkkkk Send  Literal  Selector  #kkkkkkkk  With  jjjjjjjj  Arguments 133 10000101  jjjkkkkk Send  Literal  Selector  #kkkkk  To  Superclass  With  jjj  Arguments 134 10000110  jjjjjjjj  kkkkkkkk Send  Literal  Selector  #kkkkkkkk  To  Superclass  With  jjjjjjjj  Arguments 135 10000111 Pop  Stack  Top 136 10001000 Duplicate  Stack  Top 137 10001001 Push  AcQve  Context 138-­‐143 unused 144-­‐151 10010iii Jump  iii  +  1  (i.e.,  1  through  8) 152-­‐159 10011iii Pop  and  Jump  0n  False  iii  +1  (i.e.,  1  through  8) 160-­‐167 10100iii  jjjjjjjj Jump(iii  -­‐  4)  *256+jjjjjjjj 168-­‐171 101010ii  jjjjjjjj Pop  and  Jump  On  True  ii  *256+jjjjjjjj 172-­‐175 101011ii  jjjjjjjj Pop  and  Jump  On  False  ii  *256+jjjjjjjj 176-­‐191 1011iiii Send  ArithmeQc  Message  #iiii 192-­‐207 1100iiii Send  Special  Message  #iiii 208-­‐223 1101iiii Send  Literal  Selector  #iiii  With  No  Arguments 224-­‐239 1110iiii Send  Literal  Selector  #iiii  With  1  Argument 240-­‐255 1111iiii 38 Send  Literal  Selector  #iiii  With  2  Arguments  Friday, March 22, 13
  39. 39. • An  example  method, forCompiledMethod "to show how CompiledMethod works" | foo | foo := test. ^ 1 + 2 • Bytecode:  in  System  Browser  of  Squeak/Pharo,  we  can  see  byteCode  easily –17 <20> pushConstant: test –18 <68> popIntoTemp: 0 –19 <76> pushConstant: 1 –20 <77> pushConstant: 2 –21 <B0> send: + –22 <7C> returnTop 39Friday, March 22, 13
  40. 40. displaying smalltalk bytecode • CompiledMethod • Class>>compiledMethodAt • (Integer compiledMethodAt: #factorial) symbolic • (RubyConfTW compiledMethodAt: #forCompiledMethd) symbolic • code here 40Friday, March 22, 13
  41. 41. compiler • Behavior>>compile • compile: compile: code ^self compile: code notifying: nil • compile:notifying: • compile:classified: notifying: requestor trailer: ifFail: 41Friday, March 22, 13
  42. 42. a Simple Behavior>>compile example • RubyConfTW compile: foo^42 • RubyConfTW will have a new method called foo and the code is to return the ultimate answer • (RubyConfTW compiledMethodAt: #foo) symbolic 17 <20> pushConstant: 42 18 <7C> returnTop’ 42Friday, March 22, 13
  43. 43. add a method | myClass myInstance |   myClass := Behavior new. "create anon behavior"   myClass compile: theAnswer ^42. "add a method for insta nces"   myInstance := myClass new. "create an instance"   Transcript show: myInstance theAnswer; cr. "shows 42"  43Friday, March 22, 13
  44. 44. Ruby bytecode • ruby  1.8 o cannot  find  easy  way  to  do  this • ruby  1.9  and  2.0 o ruby.c:proc_opQons() § -­‐-­‐dump=insns o YARV  InstrucQon  table o hmp://www.atdot.net/yarv/insnstbl.html,   o source  code,  or o you  can  ask  Sasada-­‐san  :-­‐) 44Friday, March 22, 13
  45. 45. For a simple hello world > rbenv exec ruby --dump=insns ~/work/ruby/test.rb == disasm: <RubyVM::InstructionSequence:<main>@/Users/freedom/work/ruby/ test.rb> 0000 trace 1 ( 1) 0002 putself 0003 putstring "hello, worldn" 0005 send <callinfo!mid:print, argc:1, FCALL|ARGS_SKIP> 0007 leave 45Friday, March 22, 13
  46. 46. Ruby KERNEL Module • it  took  me  some  Qme  to  figure  out  what  puts()  and   other  kernel  methods  are • puts  ==  KERNEL.puts  ==  $stdout.puts()?,   == disasm: <RubyVM::InstructionSequence:<main>@test.rb>================= 0000 trace 1 ( 1) 0002 putself 0003 putstring "hello, worldn" 0005 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP> 0007 pop 0008 trace 1 ( 2) 0010 getinlinecache 17, <ic:0> 0013 getconstant :Kernel 0015 setinlinecache <ic:0> 0017 putstring "hello, worldn" 0019 opt_send_simple <callinfo!mid:puts, argc:1, ARGS_SKIP> 0021 pop 0022 trace 1 ( 3) 0024 getglobal $stdout 0026 putstring "hello, world" 0028 opt_send_simple <callinfo!mid:puts, argc:1, ARGS_SKIP> 0030 leave 46Friday, March 22, 13
  47. 47. CompiledMethod in Ruby • RubyVM::InstructionSequence • = Class methods: • compile, compile_file, compile_option, compile_option=, disasm, disassemble, load, new • = Instance methods: • disasm, disassemble, eval, inspect, to_a 47Friday, March 22, 13
  48. 48. CompiledMethod in Ruby filename = ARGV[0] code = RubyVM::InstructionSequence.compile_file filename File.open "bytecode.dump", "w" do |file| file << Marshal.dump(code.to_a) end print code.disasm 48Friday, March 22, 13
  49. 49. Load saved instruction sequence • there  is  no  RubyVM::InstrucQonSequence.load,  but   there  is  iseq_s_load()  in  iseq.c #if 0 /* TBD */ rb_define_method(rb_cISeq, "marshal_dump", iseq_marshal_dump, 0); rb_define_method(rb_cISeq, "marshal_load", iseq_marshal_load, 1); #endif /* disable this feature because there is no verifier. */ /* rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1); */ (void)iseq_s_load; • So,  my  first  reacQon  is /* disable this feature because there is no verifier. */ rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1); // (void)iseq_s_load; • And  I  googled  a  bit,  found  that,  it  seems  we  can  define   an  InstrucQonSequence.load  method  to  use     iseq_s_load() • hmp://bb10.com/ruby-­‐core/2012-­‐07/msg00303.html 49Friday, March 22, 13
  50. 50. Store and load • test.rb puts “hello, worldn” puts 1+2 • store-and-load.rb filename = ARGV[0] code = RubyVM::InstructionSequence.compile_file filename File.open "bytecode.dump", "w" do |file| file << Marshal.dump(code.to_a) end code = nil File.open "bytecode.dump", "r" do |file| code = RubyVM::InstructionSequence.load Marshal.restore(file.read) end print code.disasm 50Friday, March 22, 13
  51. 51. test.rb ./ruby --disable-gems ~/work/ruby/load.rb == disasm: <RubyVM::InstructionSequence:<main>@/Users/freedom/work/ruby/ test.rb> local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1) 0000 trace 1 0002 putself 0003 putstring "hello, worldn" 0005 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP> 0007 pop 0008 trace 1 0010 putself 0011 putobject 1 0013 putobject 2 0015 opt_plus <callinfo!mid:+, argc:1, ARGS_SKIP> 0017 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP> 0019 leave 51Friday, March 22, 13
  52. 52. With some tweaks and modification to bytecode.dump ./ruby --disable-gems ~/work/ruby/load.rb == disasm: <RubyVM::InstructionSequence:<main>@/Users/freedom/work/ruby/ test.rb> local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1) 0000 trace 1 0002 putself 0003 putstring "hello, worldn" 0005 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP> 0007 pop 0008 trace 1 0010 putself 0011 putobject 1 0013 putobject 2 0015 opt_plus <callinfo!mid:+, argc:1, ARGS_SKIP> 0017 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP> 0019 answe 52Friday, March 22, 13
  53. 53. in case you didn’t get it • There is a YARV instruction called “answer” • And, the answer instruction will return “The Answer to Life, the Universe, and Everything”, which you know is 42 • http://en.wikipedia.org/wiki/ Answer_to_The_Ultimate_Question_of_Life,_ the_Universe,_and_Everything#Answer_to_th e_Ultimate_Question_of_Life. 2C_the_Universe.2C_and_Everything_.2842.29 53Friday, March 22, 13
  54. 54. Comparing bytecodes 17 <20> pushConstant: test’ 18 <68> popIntoTemp: 0 19 <76> pushConstant: 1 20 <77> pushConstant: 2 21 <B0> send: + 22 <7C> returnTop 0000 trace 1 0002 putself 0003 putstring "hello, worldn" 0005 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP> 0007 pop 0008 trace 1 0010 putself 0011 putobject 1 0013 putobject 2 0015 opt_plus <callinfo!mid:+, argc:1, ARGS_SKIP> 0017 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP> 0019 leave 54Friday, March 22, 13
  55. 55. • An  example  method, forCOmpiledMethod2: a and: b "to show how CompiledMethod works" | foo | foo := test. ^ a + b • Bytecode:  in  System  Browser  of  Squeak/Pharo,  we  can  see  byteCode  easily –17 <20> pushConstant: test –18 <68> popIntoTemp: 2 –19 <76> pushTemp: 0 –20 <77> pushTemp: 1 –21 <B0> send: + –22 <7C> returnTop 55Friday, March 22, 13
  56. 56. Some obvious differences • Smalltalk bytecodes are quite low-level, but more consistent? • String is not special • no special optimizations such as ‘op_plus’ • but Smalltalk-80 does have some primitive methods • no joke bytecode :-) 56Friday, March 22, 13
  57. 57. Smalltalk primitive method Integer>>+ + aNumber     "Refer to the comment in Number + "     aNumber isInteger ifTrue:         [self negative == aNumber negative             ifTrue: [^ (self digitAdd: aNumber) normalize]             ifFalse: [^ self digitSubtract: aNumber]].     ^ aNumber adaptToInteger: self andSend: #+ SmallInteger>>+ + aNumber     "Primitive. Add the receiver to the argument and answer with the result     if it is a SmallInteger. Fail if the argument or the result is not a     SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."     <primitive: 1>     ^ super + aNumber 57Friday, March 22, 13
  58. 58. ?? 58Friday, March 22, 13
  59. 59. Thanks!! 59Friday, March 22, 13

×