Reflection
-
[quote="Jester"]
Shade Of Mine schrieb:
Soweit ich die Diskussion verstanden habe geht es darum ob es andere objekte geben darf oder nicht.
ne, mir geht es darum ob es sie geben *muss*. und ich finde es muss nicht. dürfen tut's das wohl.
[...]quote]
Und an "wen" gehen die Informationen wenn du eine Komponente darum bittest dir Auskunft über sich selbst zu geben? Es kann natürlich auch sein das die Komponente sich selbst modifiziert und dann eine "Selbst-"Reflexion durchführt um auf die geänderte Struktur einzugehen. Aber was denn nun?
Irgendwie hab ich grad den Faden verloren ^^ kann man jmd die gegensätzlichen Meinungen kurz gegenüberstellen?
-
Jester schrieb:
Shade Of Mine schrieb:
Soweit ich die Diskussion verstanden habe geht es darum ob es andere objekte geben darf oder nicht.
ne, mir geht es darum ob es sie geben *muss*. und ich finde es muss nicht. dürfen tut's das wohl.
ob man die information nun auch von irgendwo außerhalb kommen darf ist eine andere frage.
muss nicht. ne. es muss sie nur geben dürfen.
dann ist also die frage ob information von aussen kommen darf? bestes beispiel java: class objekte beschreiben klassen und class objekte sind extern von der runtime zur verfügung gestellt. die objekte selbst kennen ihre struktur nicht - dazu braucht man externe class objekte.
ergo: die information kann (muss aber nicht) von externen resourcen bereitgestellt werden dürfen (natürlich auch von internen objekten oder dem objekt selber).
-
Shade Of Mine schrieb:
Ich trenne nicht woher die Informationen kommen - das wie und woher ist mir egal -> bei mir steht die Information selbst im Mittelpunkt.
Du vielleicht nicht, aber genau darum gehts bei Reflection. Wenn du dir eine Javaklasse schreibst und eine getMethodNames() Methode einbaust und dort nur als Daten eingetragene Strings zurück gibst, dann ist das halt kein Reflection. Da wird keiner sagen das ist Reflection, sondern nur fragen, warum du das nicht per Reflection machst. Wenn du Reflection verwendest, werden diese Informationen nämlich aus der Programmstruktur geholt und nicht aus den Programmdaten. Bei Reflection geht es nicht darum welche Daten zurückgegeben werden und was du damit machst (z.B. vorhandene Methoden aufrufen), sondern darum das mit Informationen aus der Programmstruktur (!= Programmdaten) gearbeitet wird.
-
FachmannFürReflection schrieb:
Shade Of Mine schrieb:
Ich trenne nicht woher die Informationen kommen - das wie und woher ist mir egal -> bei mir steht die Information selbst im Mittelpunkt.
Du vielleicht nicht, aber genau darum gehts bei Reflection. Wenn du dir eine Javaklasse schreibst und eine getMethodNames() Methode einbaust und dort nur als Daten eingetragene Strings zurück gibst, dann ist das halt kein Reflection. Da wird keiner sagen das ist Reflection, sondern nur fragen, warum du das nicht per Reflection machst. Wenn du Reflection verwendest, werden diese Informationen nämlich aus der Programmstruktur geholt und nicht aus den Programmdaten. Bei Reflection geht es nicht darum welche Daten zurückgegeben werden und was du damit machst (z.B. vorhandene Methoden aufrufen), sondern darum das mit Informationen aus der Programmstruktur (!= Programmdaten) gearbeitet wird.
Sprich Reflection in C++ ist unmoeglich?
Wie erklaerst du dir dann Reflection Libraries fuer C++ oder die statische Reflection ueber zB type_traits?Das Problem hierbei ist, dass du denkst alles was die Runtime macht ist Magie. Wenn ich genau das selbe mache wie die Java Runtime nur eben nicht in der Runtime sondern einer externen Library - wieso ist es dann nicht Reflection? Die Java Runtime zaubert nicht, sie kennt nur Informationen die man normalerweise nicht kennt - sie kommt an diese Informationen aber nur weil der Compiler ihr eine Liste der Methoden gibt die eine Klasse unterstuetzt. Wenn dieser Prozess nicht direkt beim Kompilieren sondern in 2 Schritten erfolgt - dann ist das in meinen Augen ein Implementationsdetail.
Ich will ein Objekt foo haben und sagen koennen: irgendwer liefere mir bitte eine Liste aller unterstuetzten Methoden so dass ich alle aufrufen kann die ein a im Namen haben.
Wenn ich soetwas machen kann, warum ist es dann wichtig ob die Java Runtime diese Information vom Compiler bekommen hat oder ob die C++ Library diese Information von einem pre-compiler bekommen hat oder ob es einfach ein allwissendes Gott-Objekt ist, dass einfach alles weiss.
Bei Java ist es zB so, dass das Objekt selber keine Informationen ueber die eigene Struktur hat. Es gibt dafuer externe Objekte die beim kompilieren automatisch miterstellt werden: naemlich die class-objekte. Diese haben Informationen ueber die einzelnen Klasse. Zufaelligerweise ist das technisch direkt in die Java Runtime eingebaut. Da aber diese Informationen ja im .class File stehen (weil sie der Compiler dort hinein schreibt) koennte man, wenn es diese Class Objekte in der Runtime nicht gaebe, sie selber schreiben.
Waere es Reflection wenn ich die Java Reflection als externe Library einbinden muesste bzw. selber schreiben muesste?
-
Shade Of Mine schrieb:
Wie erklaerst du dir dann Reflection Libraries fuer C++ oder die statische Reflection ueber zB type_traits?
statisch reflection gibt es nicht. reflection ist immer dynamisch. es bedeutet, daß ein program zur laufzeit seine eigene struktur kennt und sich selbst, wenn es nötig sein sollte, verändern kann. ein c-programm müsste z.b. seinen eigenen maschinencode analysieren, etwa mit hilfe hineincompilierter debug-infos.
so ähnlich stehts auch im englischsprachigen wikipedia-artikel.
-
In C++ kannst du nur sehr begrenzt reflection durchführen, weil hast fast keine nutzbaren Informationen über die Programmstruktur vorhanden sind, genauso wie bei C. Klar kannst du irgendwelche Frameworks oder Compiler verwenden die alle möglichen zusätzlichen Information ins Programm reinstecken und damit dann Reflection durchfürhen. Mit externen Libraries die diese Informationen nicht haben, können diese Frameworks aber schon nicht mehr viel anfangen.
Das Problem an deiner Definition ist einfach, dass du einen Anwendungsfall von Reflection zur Definition machst und dann meinst, alles mit dem du diesen Anwendungsfall nachbauen kannst ist Reflection. Das du mit Informationen über die Programmstruktur die du irgendwo her bekommen hast etwas machst ist aber nicht Reflection. Reflection ist diese Informationen aus der Programmstruktur zu holen und die Programmstruktur zu ändern (Für alle Schlaumeier: Das ist kein logisches UND).
-
Bei Java ist es zB so, dass das Objekt selber keine Informationen ueber die eigene Struktur hat. Es gibt dafuer externe Objekte die beim kompilieren automatisch miterstellt werden: naemlich die class-objekte. Diese haben Informationen ueber die einzelnen Klasse.
Objekte kennen ihre class-Objekte, also kennen Objekte auch ihre Struktur! Wieso zum Teufel sollte man da unterscheiden? Soll jedes einzelne Objekt eine Liste mit seinen Methodennamen mit rumschleppen? Hohe Kapselung und geringe Kopplung sind grundlegende Primzipien der Objektorientierten Programmierung!
-
fricky schrieb:
statisch reflection gibt es nicht. reflection ist immer dynamisch. es bedeutet, daß ein program zur laufzeit seine eigene struktur kennt und sich selbst, wenn es nötig sein sollte, verändern kann. ein c-programm müsste z.b. seinen eigenen maschinencode analysieren, etwa mit hilfe hineincompilierter debug-infos.
so ähnlich stehts auch im englischsprachigen wikipedia-artikel.
statische Reflection wie zB type_traits. Siehe Wikipedia
FachmannFürReflection schrieb:
In C++ kannst du nur sehr begrenzt reflection durchführen
Also ist es nur Reflection wenn es mehr als 50% der Reflection features von Java anbietet? Oder 48%? Oder braucht man absolute mehrheit mit >75%?
ein bisschen schwanger sein ist eine interessante definition
ogottogott schrieb:
Objekte kennen ihre class-Objekte
Wenn also die Objekte die class objekte nicht kennen, weil man zB nicht alles von einer basis klasse ableitet ist es keine reflection mehr?
-
Shade Of Mine schrieb:
FachmannFürReflection schrieb:
In C++ kannst du nur sehr begrenzt reflection durchführen
Also ist es nur Reflection wenn es mehr als 50% der Reflection features von Java anbietet? Oder 48%? Oder braucht man absolute mehrheit mit >75%?
ein bisschen schwanger sein ist eine interessante definition
Sehr schlau.
Was besseres als vollkommen zusammenhangloses zitieren um dann mit Schwachsinn darauf antworten zu könne ist dir wohl nicht mehr eingefallen.
-
FachmannFürReflection schrieb:
Shade Of Mine schrieb:
FachmannFürReflection schrieb:
In C++ kannst du nur sehr begrenzt reflection durchführen
Also ist es nur Reflection wenn es mehr als 50% der Reflection features von Java anbietet? Oder 48%? Oder braucht man absolute mehrheit mit >75%?
ein bisschen schwanger sein ist eine interessante definition
Sehr schlau.
Was besseres als vollkommen zusammenhangloses zitieren um dann mit Schwachsinn darauf antworten zu könne ist dir wohl nicht mehr eingefallen.
Man muss allerdings sagen, dass es in Java auch Dinge gibt, die man leider nicht via Reflection herausfinden kann. Das betrifft zum Beispiel die Namen von Methodenparametern. Oder einige Dinge im Zusammenhang mit Generics. Die sind ja leider mittels Erasure implementiert.
-
In C++ gibt es sehr wohl Reflection: google c++ reflection
-
Shade Of Mine schrieb:
fricky schrieb:
statisch reflection gibt es nicht. reflection ist immer dynamisch. es bedeutet, daß ein program zur laufzeit seine eigene struktur kennt und sich selbst, wenn es nötig sein sollte, verändern kann. ein c-programm müsste z.b. seinen eigenen maschinencode analysieren, etwa mit hilfe hineincompilierter debug-infos.
so ähnlich stehts auch im englischsprachigen wikipedia-artikel.
statische Reflection wie zB type_traits. Siehe Wikipedia
das ist keine reflection, auch wenn wikipedia das anders sieht. es geht nun mal nicht nur darum, metainformationen abzufragen und mit template-tricks den compiler dazu zu bewegen, speziellen code zu erzeugen. es geht ausschliesslich um laufzeitdynamik wie z.b. neue objekte und arrays zu erzeugen, von denen zur compilezeit nicht das geringste bekannt ist, kein name, kein typ usw. und diese objekte dann zu benutzen, als wären sie schon beim compilieren existent. die einzigen möglichkeiten die ich für c++ und c sehe, sowas zu machen sind:
1. das programm analysiert seinen maschinencode kann ihn verändern.
2. das programm ändert seinen quelltext und compiliert sich dann selbst.
-
Moin,
bei so viel interesse an diesem Thema, wäre das nicht ein Magazin Artikel wert?MFG
-
Was soll es bringen, wenn 50% in akzeptieren und 50% nicht, je nachdem wer ihn geschrieben hat?
-
Hoffmann schrieb:
Moin,
bei so viel interesse an diesem Thema, wäre das nicht ein Magazin Artikel wert?eigentlich nicht. man findet schon viel dazu im internet, z.b. das: http://www.petendi.de/seminare/reflection/parts/reflection_petendi_hausarbeit.pdf
-
fricky schrieb:
das ist keine reflection
Wenn ich einen C++ Interpreter nehme wird es zur Laufzeit ausgefuehrt. Wenn ich dann Typen dynamisch lade, sind die Typen zur Compilezeit sowieso nicht bekannt.
Genau das selbe mit statischer Polymorphie. Langweilige Diskussion - denn eine Trennung Runtime/Compiletime ist heutzutage nicht mehr machbar.
und bedenke: ich kann in Java auch Reflection auf nur bekannte Objekte machen - Reflection so zu definieren dass es nur auf Objekte geht die zur Zeit des Codeschreibens unbekannt waren, ist etwas gewagt. Weil somit viele Programme die die Java Reflection API verwenden ploetzlich nicht mehr in die Reflection Definition reinfallen.
Bei type_traits habe ich Typen (wenn man so will: objekte) und ich kenne einige Metainformationen nicht. Deshalb verwende ich type_traits um an diese Metainformationen zu kommen: zB, ist dieser Typ const, ist er eine Referenz - und dann manipuliere ich ihn so, dass er mir passt: ich nehme ihm das volatile und den Zeiger und mache ihn zu einer const Referenz.
Ihr seht jetzt nur: aber das passiert bei der Compiletime - aber wenn wir einen C++ Interpreter nehmen, passiert es waehrend der Laufzeit
Diese Trennung Compile/Runtime ist einfach nur veraltet.
Den Einwand von Gregor find ich super
Irgendwie finde ich es sehr schade dass die Java Definition eines Konzeptes immer die allgemeingueltige Definition sein muss. Reflection die weniger Moeglichkeiten bietet als die Java Reflection ist automatisch keine Reflection mehr - aber wenn ich eine Sprache habe die mehr Reflection Moeglichkeiten bietet als Java es tut, so ist das egal.
-
Shade Of Mine schrieb:
und bedenke: ich kann in Java auch Reflection auf nur bekannte Objekte machen - Reflection so zu definieren dass es nur auf Objekte geht die zur Zeit des Codeschreibens unbekannt waren, ist etwas gewagt. Weil somit viele Programme die die Java Reflection API verwenden ploetzlich nicht mehr in die Reflection Definition reinfallen.
Was sollen den bei dir unbekannte Objekte sein? Auf jedes Objekt das es im Programm gibt kann ich Reflection anwenden, egal ob ich das schon beim schreiben des Programms kenne oder ob ich später eine weitere Jar Datei beim Classpath meines Programms angebe und das Objekt daraus kommt. Oder was ist bei dir ein unbekanntes Objekt?
Den Einwand von Gregor find ich super
Irgendwie finde ich es sehr schade dass die Java Definition eines Konzeptes immer die allgemeingueltige Definition sein muss. Reflection die weniger Moeglichkeiten bietet als die Java Reflection ist automatisch keine Reflection mehr - aber wenn ich eine Sprache habe die mehr Reflection Moeglichkeiten bietet als Java es tut, so ist das egal.Wo hat hier jemand behauptet, dass das was in Java geht die Definition für Reflection ist?
-
Shade Of Mine schrieb:
Wenn ich einen C++ Interpreter nehme wird es zur Laufzeit ausgefuehrt. Wenn ich dann Typen dynamisch lade, sind die Typen zur Compilezeit sowieso nicht bekannt.
Genau das selbe mit statischer Polymorphie. Langweilige Diskussion - denn eine Trennung Runtime/Compiletime ist heutzutage nicht mehr machbar.
Mit dir zu diskutieren ist sinnlos. Du hast dir eine ganz Menge eigener Definitionen zurecht gelegt, die nicht den allgemeinen Definitionen entsprechen, aber du hältst sie für allgemeiner, besser und moderner und jeder der dem nicht zustimmt, der versteht es einfach nicht und denkt nicht so "fortschrittlich" und "weitblickend" wie du.
Natürlich ist die Laufzeit, Compilezeit und Interpretationszeit was anderes, auch wenn es mit JIT-Compiler und Multicoresystemen praktisch parallel ablaufen kann.
-
erdtfghj schrieb:
Oder was ist bei dir ein unbekanntes Objekt?
Siehe frickys Post.
FachmannFürReflection schrieb:
Mit dir zu diskutieren ist sinnlos. Du hast dir eine ganz Menge eigener Definitionen zurecht gelegt, die nicht den allgemeinen Definitionen entsprechen, aber du hältst sie für allgemeiner, besser und moderner und jeder der dem nicht zustimmt, der versteht es einfach nicht und denkt nicht so "fortschrittlich" und "weitblickend" wie du.
Mit dem Unterschied dass ich sie mir nicht selber ausgedacht habe, sondern von Stroustrup, Meyers, Sutter, Coplien, Stroustrup, Meyer, Armstrong und wie sie alle heissen uebernommen habe. Das Problem ist nur, diese Leute schreiben keine Buecher die jeder liest. Die Standard Java Definition von einem Konzept kann ich in jedem Anfaenger Java Buch nachlesen - und das ist auch gut. Wenn ich nur Sprache X Programmiere muss ich nur die Konzepte kennen wie sie dort vorkommen. Das Problem an Diskussionen wie diesen hier ist, dass Leute die dann nur Sprache X kennen die Definition des Konzeptes von X uebernehmen und sagen: das ist das Konzept.
Aber andere Sprachen gehen komplett anders an die Sache heran - das Konzept bleibt aber gleich, was sich aendert sind die techniken und vielleicht die Blickwinkel. Man nehme zB Objekt Orientierte Programmierung. Manche Leute sagen man braucht Klassen dafuer. Andere sagen man braucht Information Hiding, andere sagen man braucht Laufzeitpolymorphie. Was es aber wirklich ist, ist ein Konzept dass durch verschiedene techniken unterstuetzt wird. zB sind Klassen einfach praktisch weil man dadurch Vererbung hat. Aber in Prototype Sprachen hat man halt keine Klassen, dafuer Prototypen die man manipulieren kann. Das ist auch etwas unheimlich praktisches. Es sind eben 2 Auspraegungen von dem gleichen Konzept.
Und genau so ist es mit fast allen Konzepten die wir zum Programmieren verwenden. Reflection in C++ laeuft eben ueber type_traits. In JavaScript ueber Prototypes und in Java habe ich ein Class Objekt. Technisch sind diese 3 Auspraegungen enorm Unterschiedlich.
zB koennte man argumentieren dass Java keine echte Reflection bietet, weil die Prototypen aus JavaScript einfach viel flexibler und mehr bieten als die class Objekte in Java. Und natuerlich bieten die class Objekte in Java mehr Moeglichkeiten als die type_traits aus C++. Dafuer kann man in C++ eben die Typen selber veraendern - waehrend man in Java die class Objekte nicht aendern kann.
Keins ist jetzt besser oder definitiv die einzig gueltige Variante von Reflection - alles sind Auspraegungen des Wunsches Metainformationen zu bekommen und diese Manipulieren zu koennen. Jede Sprache setzt dies eben so gut um wie es innerhalb der Sprache Sinn macht.
und es ist gut, dass die Sprachen unterschiedliche Ansaetze suchen. Die Wuensche von den Programmierern sind sich ziemlich aehnlich - aber man kann nicht alle Wuensche erfuellen. Deshalb muss es Sprachen geben die Ansaetze waehlen die eben diese Wuensche in den Vordergrund setzen und andere die andere als wichtiger Erachten. Und durch diese Verschiebung der Prioritaeten entstehen neue Blickwinkel - neue Blickwinkel auf bestehende Konzepte oder sagen wir vielleicht lieber Ideen dazu. Die Idee dass ich Metainformationen bekommen und manipulieren kann ist ueberall vorhanden. Die Auspraegung dagegen ist enorm unterschiedlich - zB ist in Sprachen mit dynamischen Typen eine manipulation der Struktur eines Objektes viel einfacher als in einer Sprache mit einem statischen Typsystem. Aber ist Reflection deshalb nur Reflection wenn ich ein dynamisches Typsystem habe?
Natürlich ist die Laufzeit, Compilezeit und Interpretationszeit was anderes, auch wenn es mit JIT-Compiler und Multicoresystemen praktisch parallel ablaufen kann.
Man kann es mittlerweile nicht mehr streng trennen. Man kompiliert teilweise nach der Laufzeit. Man Interpretiert vor der Laufzeit und nicht waehrend - insofern ist eine Trennung einfach nicht mehr vernuenftig moeglich.
-
Shade Of Mine schrieb:
Dafuer kann man in C++ eben die Typen selber veraendern - waehrend man in Java die class Objekte nicht aendern kann.
Ich weiß jetzt nicht genau, was Du meinst, aber hast Du schonmal etwas von der Instrumentation-API von Java gehört?