1 / 56

Orphan Objects and Other Reflective Techniques

Explore the concept of reflection in Smalltalk, including introspection and the ability to change objects at runtime.

schee
Download Presentation

Orphan Objects and Other Reflective Techniques

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Orphan Objects and Other Reflective Techniques Brian Foote The Refactory, Inc. 23 April 2001 Smalltalk Solutions ‘02 Orphan Objects

  2. Reflective Programming in Smalltalk Definitions Building a Language Out of Objects Examples Orphan Objects

  3. Frequently Asked Questions Q: What isreflection? A: It’s about building your language out of first-class, dynamic objects that you can look at and change at runtime. Orphan Objects

  4. Frequently Asked Questions Q: Haven’t people really been doing this for a long time? A: They certainly have. Smalltalk programmers have been doing this since the ‘70s. Orphan Objects

  5. Reflection from the Eisenhower Era Hence, [the machine] can, in particular, change the orders (since these are in memory!)--the very orders that control its actions --John Von Neumann 1958 Orphan Objects

  6. Frequently Asked Questions Q: What about efficiency? A: Orphan Objects

  7. Frequently Asked Questions Q: What about efficiency? A: There are a variety of techniques that can be used to make reflective systems faster. Orphan Objects

  8. Frequently Asked Questions Q: Isn’t reflection dangerous? A: Yes! You bet it is! A: Yes, if you are not careful. A: Yes, but you can make it safer. A: Yes, but so is crossing the street. Orphan Objects

  9. Frequently Asked Questions Q: Isn’t reflection just a fancy name for a few clever hacks? A: Well, that and so much more... Orphan Objects

  10. Frequently Asked Questions Q: Why is so much of the reflection literature so hard to read? A: This is due, in part, to the area’s AI heritage... Orphan Objects

  11. Reflective Terminology introspection reflection reification Orphan Objects

  12. Reflective Terminology infinite regress causal connection reflective tower Orphan Objects

  13. Introspection When a program can look at at the objects from which it is built Smalltalk has a rich, comprehensive, indeed, unrivaled collection of introspective facilities Orphan Objects

  14. Reflection When a program can change the objects from which it is built Smalltalk represents as much as it can as as first-class dynamic objects, and you can change them at runtime. Orphan Objects

  15. Consider these Meta considered harmful “Meta” considered harmful Orphan Objects

  16. Neat Hack Hall of Fame Parentless Objects Does Not Understand Metaobjects Lightweight Classes Method Wrappers Byte Code Manipulation Compiled Method Copying Context Manipulation Source Generation Association Hacks Becomes Class Change Instance Variable At Methods On-Demand Orphan Objects

  17. Objects themselves Object Orphan Objects

  18. Object Introspection Object size == basicSize hash identityHash printOn: storeOn: dependents ... allOwners firstOwner nextInstance ownerAfter: instVarAt: isKindOf: class isMemberOf: respondsTo: Orphan Objects

  19. Example: AccessibleObjects Demonstrates: doesNotUnderstand: instVarAt: instVarAt:put: at: at:put: Orphan Objects

  20. Accessible Objects AccessibleObject class methods for: examples example "AccessibleObject example" | temp | temp := AccessibleObject new. temp dog: 'Fido'. temp cat: 'Tabby'. Transcript print: temp dog; cr. Transcript print: temp items; cr. temp keysDo: [:key | Transcript print: key; cr]. Transcript print: (temp variableAt: #items); cr. Transcript endEntry Orphan Objects

  21. Accessible Objects AccessibleObject methods for: accessing at: key "Return the object associated with the given key..." ^self valueAt: key at: key put: value "Store the indicated value at the designated place in our item dictionary... " ^self valueAt: key put: value size "Let's say our size is the size of our item dictionary plus our number of instance variables..." ^self items size + self instVarNames size Orphan Objects

  22. Accessible Objects AccessibleObject methods for: accessing valueAt: key "Return the object associated with the given key..." ^self valueAt: key ifAbsent: [self errorKeyNotFound] valueAt: key put: value "Store the indicated value at the designated place in our item dictionary, unless there is an instance var by that name..." items isNil ifTrue: [items := IdentityDictionary new: 16]. (self hasVariableNamed: key) ifTrue: [^self variableAt: key put: value] ifFalse: [^items at: key put: value] Orphan Objects

  23. Accessible Objects AccessibleObject methods for: instance variable access allInstVarNames "Define a shorthand for this class method..." ^self class allInstVarNames hasVariableNamed: name "Say whether we have a variable by the given name..." ^(self variableIndex: name) ~= 0 instVarNames "Define a shorthand for this class method..." ^self class instVarNames Orphan Objects

  24. Accessible Objects AccessibleObject methods for: instance variable access variableAt: name "Return the named value..." | index | index := self variableIndex: name. index = 0 ifTrue: [self error: 'Bad instance variable name...']. ^self instVarAt: index variableAt: name put: value "Set the named instance variable to the indicated value..." | index | index := self variableIndex: name. index = 0 ifTrue: [self error: 'Bad instance variable name...']. ^self instVarAt: index put: value variableIndex: name "Return the instance variable index for this name, or zero..." ^self class allInstVarNames indexOf: name asString. Orphan Objects

  25. Accessible Objects AccessibleObject methods for: error interception doesNotUnderstand: aMessage "Refer messages we don't understand to our item dictionary..." | selector name args | selector := aMessage selector. name := (selector copyWithout: $:) asSymbol. args := aMessage arguments. (self hasVariableNamed: name) ifTrue: [args size = 0 ifTrue: [^self variableAt: name] ifFalse: [^self variableAt: name put: (args at: 1)]]. (items respondsTo: selector) ifTrue: [^items perform: selector withArguments: args]. args size = 1 ifTrue: [^self valueAt: name put: (args at: 1)] ifFalse: [^self valueAt: name ifAbsent: [^super doesNotUnderstand: aMessage]] Orphan Objects

  26. Classes and Behavior Behavior ClassDescription Class Metaclass Orphan Objects

  27. Organizations ClassBuilder SystemOrganizer ClassOrganizer ClassCategoryReader Orphan Objects

  28. Code Representation MethodDictionary CompiledMethod ByteArray BlockClosure Orphan Objects

  29. Runtime Enviroment Context MethodContext/BlockContext Message MessageSend Orphan Objects

  30. Exceptions and Events Event Exception Signal SignalHandler SignalCollection HandlerList Orphan Objects

  31. Process Scheduling Process ProcessScheduler Semaphore SharedQueue Orphan Objects

  32. Viewing the Program Debugger Decompiler Inspector ChangeList <Browsers> Orphan Objects

  33. Making a Promise Future methodsFor: ‘demonstration’ demo | f | f := Future promising: [2+2]. f printString '4.0' Future class methodsFor: 'instance creation' promising: aBlock | aFuture | aFuture := self new. ^aFuture promising: aBlock Orphan Objects

  34. Creating an Orphan nil subclass: #Future instanceVariableNames: ‘semaphore ' classVariableNames: ‘ ' poolDictionaries: ' ' category: ‘Reflection-Examples’ In VisualWorks, ClassBuilder does the rest. Default implementations of doesNotUnderstand: and class are provided. Orphan Objects

  35. We’ll do it eventually... Future methodsFor: 'initialization/dispatching' promising: aBlock "Create a semaphore, and fork a block that will signal it. The result of this block is stored in result..." semaphore := Semaphore new. [result := aBlock value. semaphore signal] fork. ^self Orphan Objects

  36. Keeping a Promise doesNotUndertand: aMessage "If this is our init message, let it by..." aMessage selector == #promising: ifTrue: [^super perform: aMessage selector withArguments: aMessage arguments]. "Wait until our result is available..." semaphore wait. "If our result is a SmallInteger, it has no oop.." (result isKindOf: SmallInteger) ifTrue: [result := result asFloat]. "Become the result and do the deferred message..." result become: self. ^self perform: aMessage selector withArguments: aMessage arguments Orphan Objects

  37. Metaobjects and Lightweight Classes Orphan Objects

  38. Compiler Classes Compiler Decompiler CodeRegenerator Scanner SmalltalkCompiler Orphan Objects

  39. Compiler Support CodeStream DefineOpcodePool MethodNodeHolder ProgramNodeEnumerator ScannerTable <more> Orphan Objects

  40. Variables and Scopes ArgumentVariable InstanceVariable LocalScope LocalVariable NameScope NullScope PseudoVariable ReceiverVariable RemoteVariable StaticScope StaticVariable TemporaryVariable UndeclaredVariable VariableDefinition Orphan Objects

  41. Parse Tree Nodes ProgramNode MethodNode ParameterNode StatementNode ReturnNode ValueNode ArithmeticLoopNode AssignmentNode CascadeNode ConditionalNode LeafNode BlockNode LiteralNode VariableNode LoopNode SequenceNode SimpleMessageNode MessageNode Orphan Objects

  42. Smalltalk SystemDictionary Association/VariableBinding <class and pool variables> Orphan Objects

  43. Storage and Garbage ObjectMemory MemoryPolicy WeakArray WeakDictionary Orphan Objects

  44. Levels of Representation Source Compiler Parse Node ProgramNode ProgramNode Byte Code VM Decompiler Native Code Orphan Objects

  45. Ways to Wrap Source Code Modifications Byte Code Modifications New Selectors Dispatching Wrappers Class Wrappers Instance Wrappers Method Wrappers Orphan Objects

  46. Compiled Methods Orphan Objects

  47. Method Wrappers Orphan Objects

  48. Method Wrappers valueWithReceiver: anObject arguments: args self beforeMethod. ^[clientMethod valueWithReceiver: anObject arguments: args] valueNowOrOnUnwindDo: [self afterMethod] originalMethodName: argument ^#() receiver: self value: argument Orphan Objects

  49. Multimethods OptimizingVisitor>>visitWithNode: aNode <ParseNode> ^self value optimized OptimizingVisitor>> visitWithNode: aNode <VariableNode> ^aNode lookupIn: self symbolTable Orphan Objects

  50. Parse Tree Orphan Objects

More Related