About
fv_2007
Agile innovative developer with deep insight into lots of platforms, technologies and protocols. Absolute “early adopter” in Web 2.0 technologies and more. Large professional network and eagerly talking about architecture, strategy, design patterns, restful ressources, object-oriented thinking and modeling languages such as PML. Special interest in programminglanguages constructs, knowledge on languages like Smalltalk, Erlang, Java, Clojure, Scala, Ruby... read more
Follow
Feedfavicon
Comments
Language

Reflection VS Introspection October 22, 2007 01:54 over 2 years ago

Jeg sad på en konference og var ukoncentreret i mild grad da Dr. Nic Williams pludselig sagde noget som fik min opmærksomhed til 100 procent. Hans tale var på dynamisk adfærd og metaprogrammering, han påpegede at der er en klar distinktion mellem reflection og introspektion som jeg ikke før har tænkt på.

At jeg først er begyndt at tænke over dette begreb nu er gået lidt ud over mine nærmeste kollegaer i jagten efter en klar definition. Det viste sig at være noget nær umuligt.

Derfor er her mr. Sestoft med et citat:

Friedman and Wand “Friedman:1984:ReificationReflection” gave a simpler, more concrete version of Smith’s ideas. Furthermore, they introduced a distinction between reification and reflection: `We will use the term “reification” to mean the conversion of an interpreter component into an object which the program can manipulate. One can think of this transformation as converting a program i.e. the expression being evaluated) into data. We will use the term “reflection” to mean the operation of taking a program-manipulable value and installing it as a component in the interpreter. This is thus a transformation from data to program.’ As can be seen, these definitions do not agree entirely with the meaning of reflection in Java and C#. Friedman and Wand’s notion reification seems similar to reflection in Java and C#, whereas their notion of reflection seems related to runtime code generation, the subject of the next chapter.

Når man taler om introspection så er det gerne som modsætning til intercession. Det første betyder at observere (sig selv), det andet at modificere (sig selv).

introspection = reification (i Friedman og Wand’s forstand)
intercession = reflection (i Friedman og Wand’s forstand)

I Java bruger overvejende termen “reflection” til at betyde “introspection” (altså “reification” i F&W forstand): med java.lang.reflect kan man finde en klasses metoder, felter, konstruktører mv, men man kan ikke tilføje nye klasser eller medlemmer.

Introspection – see behaviour
Reflection – change behaviour

Introspection er altså den egenskaben til at kunne betragte sig selv som klasse objekter og klasse metoder og reflection er evenen til at kunne ændre sig.

Og måske er det bare for langhåret til nogen gider at tage notits af det så derfor vil jeg bruge et par billeder som jeg fik på samme konference. Herefter vil Java bliver set analog til Keith Richards, og Ruby vil blive set analog til Neo in the Matrix.

Keith – Not so cute anymore, can’t change his behaviour
Neo – Knows about his environment, can adapt behaviour

Introspection – see behaviour

Siden tidlige versioner af Java har der været en metode til at indhente information om objekter, deres klasser og deres metoder. Der findes et Class objekt og et Method objekt hvorigennem det er muligt at invoke metoder dynamisk selv om Java er et statisk sprog med en fast syntaks.


Keith keith = new Keith();
Method method = Keith.class.getMethod(“setPinCode”);
method.invoke(keith, new Object[]{"Play old songs"});

På samme måde kan man i Ruby spørge efter class objekt og metoder. Men metoder er returneret som Strings i Ruby, ikke som objekt. Man kan dynamisk invoke metoder blot ved at sende en besked med argumenter.


neo = Person.new
neo.class # => Person
neo.methods # => [.. ‘activity’, ‘activity=’…]
neo.send(“activity=”, “Stop bullets mid-air”)

Reflection – change behaviour

Her kan jeg ikke vise noget Java kode idet Java ikke supportere refleksion. Så Java Reflection API burde hede Introspection API. I Java kan man ikke ændre klasser eller interfaces under kørslen.

Ruby har ret vide grænser for at manipolere klasser og metoder. Her tilføres dynamisk en metode til en klasse. På klassen Bank vil jeg tilføre en metode som kan vise mig pincoden.


class Bank
def method_missing(*agrs)
“private information”
end
private
def pincode
(1..10).to_a
end
end

Bank.send :define_method, :show do
self.send :pincode
end

b = Bank.new

puts “Show my pin code #{b.pincode}”
puts “Show my pin code #{b.send :pincode}”
puts “Use dynamic added method #{b.send :show}”

Med reflection og introspektion kan man, konceptuelt, manipolere koden som den var data. Refleksion betyder altså at man har et programmerbart programmeringssprog.


By Frank Vilhelmsen - 2 tags: java ruby - Add comment