PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [RGSS] Erste Gehversuche liefern merkwürdige Fehlermeldung



UhuSchuhu
11.11.2007, 22:04
Da der 2k mir doch zu wenig Umfang für mein Projekt liefert bin ich nun doch auf den XP umgestiegen. Da ich ein bisschen Erfahrung im Programmierbereich mitbringe war das einsteigen in Ruby kein Problem.

Nun bekomme ich aber bei meiner ersten selbst geschriebenen Methode eine sehr merkwürdige Fehlermeldung.


def status(progress)

#The status bar display.
#Takes integer progress (from 1-100) - progress of the building in percent

if progress > 100
return false
end

statusbar = Sprite.new

statusbar.bitmap = RPG::Cache.picture("baufortschritt")
print statusbar.bitmap

end

Ich bekomme die Fehlermeldung "#<Bitmap:0x12c5c00>". Das merkwürdigste ist aber, dass ich die Meldung zweimal gezeigt bekomme. Das Anzeigen des Bildes funktioniert allerdings einwandfrei.

Und ein Nachtrag: Wieso verschwindet das Bild nach einiger Zeit von alleine, bzw wie kann ich das verhindern?

MagicMagor
11.11.2007, 23:03
Ich bekomme die Fehlermeldung "#<Bitmap:0x12c5c00>". Das merkwürdigste ist aber, dass ich die Meldung zweimal gezeigt bekomme. Das Anzeigen des Bildes funktioniert allerdings einwandfrei.
Dabei handelt es sich nicht um eine Fehlermeldung sondern um das Ergebniss deines print-Aufrufes. Ruby zeigt dir hier die interne ID/Speicheradresse (weiß nicht mehr genau was) deines Objektes, sowie die entsprechende Klasse (Bitmap).
print benutzt, soweit ich mich richtig entsinne die methode .to_s um aus einem Objekt einen anzeigbaren String zu machen. Die meisten gängigen Klassen wie Integer oder Float überschreiben die to_s-Methode, die jedes Objekt von der Klasse "Object" erbt, mit etwas sinnigem. Das Ergebnis da oben dürfte die Anzeige von to_s sein, wie sie in Object definiert ist.
Anmerkung:
Ich persönlich nutze zum Debuggen nicht print sondern "p". Das ist nicht nur kürzer zu schreiben, p benutzt auch eine andere Methode als print um einen anzeigbaren String zu erhalten, namentlich "inspect", sofern ich mich richtig erinnere. Ist deutlich besser zu lesen (Vergleiche einfach mal print([1,2,3]) und p([1,2,3]))

Ich kann nur spekulieren warum die Meldung zweimal kommt, vermutlich weil deine Methode von irgendwo zweimal aufgerufen wird.



Und ein Nachtrag: Wieso verschwindet das Bild nach einiger Zeit von alleine, bzw wie kann ich das verhindern?
Du speicherst dein Sprite in einer lokalen Variable (keinerlei Sonderzeichen am Anfang des Namens). Der Gültigkeitsbereich einer lokalen Variable, die innerhalb einer Methode auftaucht ist nur der entsprechende Methodenaufruf selber. Sobald die Methode durchlaufen wurde, verschwindet deine Variable wieder aus dem Speicher. Allerdings sind alle Variablen, die auf komplexere Objekte verweisen Pointer, und somit verschwindet nur die Variable, nicht aber das Objekt (hier dein Sprite).
In Ruby gibt es einen sog. Garbage Collector der sich merkt wieviele gültige, Verweise es auf ein im Speicher liegendes Objekt gibt. Du erstellst ein komplett neues Sprite mit einem Verweis (deine lokale Variable), sobald die Methode durchlaufen wurde verschwindet selbige wieder, wodurch auf dein Objekt kein gültiger Verweis mehr existiert. Hier tritt nun der GC in Aktion und "räumt" hinter dem Programmierer auf und löscht das Objekt aus dem Speicher. Aufgrund der Art wie der GC intern funktioniert (markieren und löschen) gibt es immer eine gewisse Zeitspanne zwischen dem Verschwinden des letzten Verweis und dem tatsächlichen Löschen des Objektes.

Wie du das Problem löst? Eine einfache, aber mMn sehr unschöne Version ist die Verwendung einer globalen Variable. Globale Variablen beginnen mit dem Symbol $ vor dem Variablennamen. Viel schöner aber auch etwas aufwendiger ist es, wenn du deine Daten in Module und Klassen kapselst.

UhuSchuhu
11.11.2007, 23:17
Zu 1.

Das print war garnicht zum debuggen gedacht. In dem Tutorial stand es immer dabei, so dass ich davon ausgegangen bin, dass RPG::Cache.picture nur zum Vorladen und der print-Teil zum Anzeigen dient. Danke für deine Erläuterung.

Zu 2.

Auch danke für diese Erklärung. An die Klassen werde ich mich morgen wagen, so weit wollte ich direkt am ersten Tag noch nicht gehen ;)

-KD-
15.11.2007, 20:06
Hm, ich vermute mal das du mit Programmiererfahrung meinst, dass du bereits eine prozedurale Sprache beherrschst. Diese Erfahrungen, die dir beim Erstellen von Algorithmen sicher helfen werden, kannst du aber nicht 1:1 auf eine objektorientierte Sprache übertragen. Da ist der Ablauf ein ganz anderer.

Ich möchte an der Stelle mal auf mein eigenes Rubytutorial (siehe Signatur) verweisen, welches sich im zweiten Kursteil sehr intensiv mit den Besonderheiten der objektorientierten Programmierung beschäftigt. Im dritten Kursteil werden dann auch Anwendungsbeispiele im Maker beschrieben. Den ersten Teil kannst du wohl auslassen, da dieser sich eher an die Programmieranfänger richtet.

UhuSchuhu
18.11.2007, 02:18
Hm, ich vermute mal das du mit Programmiererfahrung meinst, dass du bereits eine prozedurale Sprache beherrschst. Diese Erfahrungen, die dir beim Erstellen von Algorithmen sicher helfen werden, kannst du aber nicht 1:1 auf eine objektorientierte Sprache übertragen. Da ist der Ablauf ein ganz anderer.
Hm, ich weiß nicht, was prozedurale Sprachen sind, aber ich beherrsche keine Programmiersprache wirklich. Ich habe mich nur immer wieder mal (halbherzig) mit dem Thema Programieren auseinandergesetzt und irgendwann entnervt (meißtens, weil sich Ergebnisse nicht schnell genug eingestellt haben ;) ) aufgegeben. Die einzige Sprache, mit der ich mich wirklich intensiv auseinandergesetzt habe ist die Scriptsprache Jass, die im Editor von Warcraft 3 benutzt wird (hier gab es dank vorhandener Engine schnell genug was zum angucken).
Aber ich weiß dadurch, was Variablen sind, wie man ihnen einen Wert zuweißt, wie ein Array funktioniert und was Operatoren sind.



Ich möchte an der Stelle mal auf mein eigenes Rubytutorial (siehe Signatur) verweisen, welches sich im zweiten Kursteil sehr intensiv mit den Besonderheiten der objektorientierten Programmierung beschäftigt. Im dritten Kursteil werden dann auch Anwendungsbeispiele im Maker beschrieben. Den ersten Teil kannst du wohl auslassen, da dieser sich eher an die Programmieranfänger richtet.Du wirst es kaum glauben, aber ich habe mit deinen Tutorials gearbeitet. Nur habe ich den zweiten Teil übersprungen und direkt beim dritten angefangen, weil ich am ersten Ruby-Tag nicht direkt mit so schwerer Kost anfangen wollte. ;)

-KD-
18.11.2007, 16:12
Naja, die Tutorials bauen aufeinander auf (RGSS ist kein einfaches Ruby!). Es war für mich auch nicht einfach zu entscheiden, wann man mit der Praxis anfangen sollte. Sicherlich ist es für den Leser langweilig ein ganzes Kapitel über OOP zu lesen ohne eine einzige Anwendungsaufgabe. Nur ich will auch nicht, dass man sich direkt auf solche Anwendungsskripte stürzt und wie verrückt programmiert, ohne zu wissen, was man da eigentlich macht (das Gefühl habe ich nämlich bei vielen Scripten die man so bei Creation Assylum und rmxp.org findet X_x).

Aber gerade das zweite Kapitel ist extrem wichtig, da es die Zusammenhänge vermittelt. Wenns irgendwo eine Stelle gibt, die zu abstrakt ist und wo ein Beispiel sinnvoll wäre, dann kannste das gerne sagen (PM oder in den Diskuss schreiben ). Dann kann ich das immer noch ausbessern.

Ich seh grad, in meinem Tut gibt es tatsächlich eine Stelle wo einem Sprite ein Bitmap zugewiesen wird, welches dann per print ausgegeben wird. Erm, das print bedeutet aber eben nicht, dass die Grafik angezeigt wird. Es zeigt nur die Speicheradresse des Grafikobjekts an. Eigentlich sollte das nur ein kleiner Test sein, um zu zeigen, dass Sprite#bitmap ein Getter- und Setter-Attribut von Sprite ist (ein Thema, das wie vieles andere auch im zweiten Teil behandelt wird ^^).

MagicMagor
19.11.2007, 10:36
Die Sache mit OOP in Ruby ist, daß die gesamte Sprache auf diesem Konzept aufbaut, die ganze Philosophie der Sprache ist OOP. Ohne Grundkentnisse in OOP wird dir das Verhalten von Ruby an vielen Stellen seltsam oder unverständlich vorkommen. Wenn du aber ein wenig von OOP weißt, eröffnet sich erst der Gedanke hinter der Art wie Ruby arbeitet und das Arbeiten damit wird viel leichter (weil vieles genauso funktioniert wie man es sich dann anfangs denkt/wünscht).

OOP ist zwar ein abstraktes Konzept zur Programmierung, aber die Grundzüge sind nicht wahnsinnig kompliziert oder schwierig zu verstehen.

UhuSchuhu
19.11.2007, 17:05
Okay. Stop. Ich wollte mich nicht direkt _am ersten Tag_ (damals! kurz nach dem Krieg!) nicht direkt mit abstrakten Dingen beschäftigen, sondern etwas zu sehen haben. Was, das ich anfassen kann, etwas, das mich motiviert, weiterzumachen. Ich habe halt versucht, ein Bild darzustellen. Das war _am ersten Tag_, vor relativ genau _acht_ Tagen. Damals schrieb ich: "An die Klassen werde ich mich morgen wagen". Morgen war vor _sieben_ Tagen.

Von daher darf dann bitte aufgehört werden auf mich einzureden, das Thema ist lange durchgekaut und mitlerweile ist objektorientiertes Ruby die dritte Fremdsprache, die ich spreche. ;)