Was macht der Befehl "self" genau?

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

 

mpreu

Betreff: Was macht der Befehl "self" genau?

BeitragDi, Jul 02, 2013 17:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Wozu ist der genau da?
Zugriff innerhalb funktionen eines types auf variablen soweit ich weiß.
Wie kann man das in bb umschreiben?

ist self eigentlich nur eine vereinfachung um zeit zu sparen?
wie sähe dies in bb aus?

Tennisball

BeitragDi, Jul 02, 2013 18:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi,

Zitat:
Zugriff innerhalb funktionen eines types auf variablen soweit ich weiß.

Ich würde sagen: Zugriff innerhalb Methoden eines Objektes (eines Types) auf dessen individuelle Eigenschaften.

In BB gibt es so etwas nicht. BB-Types haben keine Methoden und somit hat ein Objekt auch nicht mal eine Gelegenheit auf seine eigenen Eigenschaften zu referenzieren.

Zitat:
Ist self eigentlich nur eine vereinfachung um zeit zu sparen?

Nein. Man kann es dazuschreiben, wenn man möchte, je nach Geschmack. Hat man z.B. jedoch (in BMax) eine Eigenschaft und einen Parameter einer Methode, die beide gleich heißen, so ist (innerhalb der Methode) das Self nötig, um auf die Eigenschaft statt den Parameter zu verweisen.

Gruß,
Tennisball


Edit:
Ein Workaround für BB sähe dann wohl ca. so aus (Pseudocode):
BlitzBasic: [AUSKLAPPEN]
Type TDing
Field bla%
Field blub%
End Type

Function TDing_AddBlaToBlub( ding.TDing )
ding\blub = ding\blub + ding\bla
End Function


Local ding.TDing = New TDing
ding\bla = 7
ding\blub = 8
TDing_AddBlaToBlub( ding )
Print( ding\blub )

Das ist natürlich unschön, aber in BB bleibt einem nicht wirklich was anderes übrig soweit ich weiß.
 

mpreu

BeitragDi, Jul 02, 2013 18:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Methoden meinte ich ja.
Da ich mich auf BB bezog nannte ich natürlich Funktion.

Danke für die schnelle Antwort.

DAK

BeitragDi, Jul 02, 2013 23:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Methoden und Funktionen sind etwas deutlich anderes und müssen unterschieden werden.

Eine Methode hat ein Objekt, dem sie zugeordnet ist. Eine Funktion nicht. Eine Funktion hat also kein Self.

Echtwelt-Beispiel:

Hund.füttern() ist eine Methode. Füttern gehört fix zu einem Objekt Hund. Du kannst nicht einen Hund füttern, wenn kein Hund da ist. Self ist dann der Hund, über den aufgerufen wird. Hund muss dann immer ein konkretes Objekt sein. Man kann also nicht den Typ Hund füttern, ohne einen konkreten Hund da zu haben.
Aufrufen würde man diese Methode dann über das konkrete Objekt, also z.B.: Hasso.füttern(). Hund.füttern() würde nicht funktionieren.

Arbeitsstelle.suchen() ist eine Funktion. Diese Funktion lässt sich aufrufen, ohne dass es dazu eine konkrete Arbeitsstelle gibt. Dabei gibt es kein Self, da es keine bestimme Arbeisstelle gibt, auf die das dann aufgerufen wird.
Aufgerufen wird diese Funktion dann über den Typnamen: Arbeitsstelle.suchen().
Gewinner der 6. und der 68. BlitzCodeCompo
 

mpreu

BeitragMi, Jul 03, 2013 1:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weiß, ich weiß...nur Funktionen sind mir halt noch so geläufig....
Macht der Gewohnheit eben...hihi
 

PhillipK

BeitragDo, Okt 03, 2013 10:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Mein rat:
Schmeiß das wissen über BB Types über board und lern die blitzmax Types einfach neu *g*
Keine vergleiche, kein nostalgisches schwelgen.


Um dir self noch ein wenig zu verdeutlichen, mal ein kleines beispiel.

Du hast in deinem Programm 2 Types, Type Mann und Type Bier.

Man(n) hat eine trunkenheitsanzeige und Bier einen füllstand.
BlitzMax: [AUSKLAPPEN]
Type Mann
Field name:String
Field geld:Int 'ganze euros
Field Trunkenheit:Float 'dezimaldarstellung einer prozentzahl. 100% is kritisch ^^

Field getraenk:Bier

Function Erstellen:Mann(name:String, geld:Int)
'wir befinden uns hier im globalen funktionsbereich der klasse. DH: Alles was FIELD ist kann nicht benutzt werden.
'erschaffen wir also einen neuen mann und geben ihm etwas bier :)

Local ganzer_kerl:Mann = New Mann()
ganzer_kerl.name = name
ganzer_kerl.Trunkenheit = 0.0

If ganzer_kerl.getraenk = Null Then ganzer_kerl.getrank = ganzer_kerl.BestelleBier()

Return ganzer_kerl
End Function

Method BestelleBier:Bier()
'Hier befinden wir uns im methodenbereich. Das heißt: Alle globalen funktionen können erreicht werden sowie andere methoden.
'man kann sagen, das wir uns innerhalb des mannes befinden :P Alle felder sind auf ihn zugeschnitten. Sein geld, sein name, seine trunkenheit.

Local b:Bier = Null

'Beachte das self: hätte diese methode einene parameter mitbekommen, der geld heißen würde, so wäre das self pflicht!
'andernfalls ist es optional.
If Self.geld > 0 Then
b = New Bier()
Self.geld :-1
EndIf

'Nebenbei: Self lässt sich mit "Selbst" oder weiter "Eigenes" übersetzen. Grob halt.
'so klingt das ganze doch logisch oder? :) Unser eigenes Getränk wird auf das objekt der locale b gelenkt :)
'die andere beiden haben ihr eigenes bier..
Self.getraenk = b
Return b
End Method

Method Update:Int()
If Self.getraenk Then
If Self.getraenk.Drink() > 0 Then
Self.Trunkenheit :+ Rnd(0.001,0.005)
Else
Self.getraenk = Null
EndIf
Else
Self.getraenk = Self.BestelleBier()
EndIf
Return 1
End Type

Type Bier
Field fuellung:Float = 0.5 '1.0 = 1 liter *g*

Method Drink:Int()
If Self.fuellung > 0.0 Then
Self.fuellung :- 0.01
Return 1
EndIf
Return 0
End Method
End Type

'Bemerke: Mann ist der name des Types. Wir können niemals eine variable dieses namens erschaffen.
'Mann wird IMMER als Type referenziert. Nutzen wir den "." (punkt), greifen wir auf die GLOBALEN funktionen der klasse zu.
'in diesem fall ein construktor dem wir parameter geben.
Local harald:Mann = Mann.Erstellen("harald", 5)
Local manni:Mann = Mann.Erstellen("Manni", 8)
Local jungspund:Mann = Mann.Erstellen("Juengling", 1)

While True


harald.Update()
manni.Update()
jungspund.Update()
Wend

Achtung, schwachsinnscode.

Aber zur erklärung:
3 Männer gehen in die Bar.
Jeder hat sein eigenes geld, sein eigenes getränk und seine eigene trunkenheit.
Obwohl sie alle vom Type Mann sind, sind sie doch unterschiedlich.
Ich habe überall, obwohl nicht grade notwendig, self verwendet. Das ist übrigends grade zu anfang ein sehr guter stil zum lernen.
Mir ist es zb schon oft passiert, das ich eine Methode ala "SetPositionX(x:int)" hatte, und dazu ein field x im objekt selber.

Was habe ich also getan? genau. x = x. Dh ich habe die lokale variable sich selber zugewiesen und ewig den fehler gesucht, warum mein objekt nicht an position x gesetzt wird.

Schreibt man Self.X wird allerdings direkt im objektscope das feld angesprochen, nicht die lokale.
BlitzMax: [AUSKLAPPEN]
Method Pseudo:Int(x:Int)
x = x 'wir weisen der lokalen variable "x" sich selbst zu. Fehler! bzw blödheit :D
Self.x = X 'wir weisen dem objekt eigenem feld "x" den wert der lokalen variable "x" zu. So is' korrekt.
End Method

Xeres

Moderator

BeitragDo, Okt 03, 2013 16:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Nichts gegen eure Beispiele, aber es geht auch ganz kurz:
BlitzMax: [AUSKLAPPEN]
Rem
Zugriff auf verschiedene Scopes
EndRem


SuperStrict

Global konstante:String = "Global"

Type TTest

Field konstante:String = "Self"

Method Show(konstante:String = "Parameter")
Print("Globale enthält: "+ .konstante )
Print("Self enthält: "+ Self.konstante )
Print("Parameter enthält: "+ konstante )
EndMethod

EndType

Local t:TTest = New TTest
t.Show()

Innerhalb der Methode ist der Parameter die neuste Variable und wird normal angesprochen. Wäre sie nicht vorhanden, könnte man so auch auf das Field zugreifen, das hier Eindeutig mit Self referenziert wird. Und zu guter Letzt kann man mit einem einfachen Punkt zurück auf den Globalen Namensraum verweisen.
Ich würde wenn möglich nicht auf Self verzichten - aber das kommt auf dein Benennungsschema an.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

PhillipK

BeitragFr, Okt 04, 2013 11:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Hoi xeres,

danke für das beispiel. Ich hab schon öfters gerätselt, wie ich in einem solchen falle an Globale rankomme. o.O

BladeRunner

Moderator

BeitragFr, Okt 04, 2013 12:06
Antworten mit Zitat
Benutzer-Profile anzeigen
anstelle nurden Punkt geht es auch mit super.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

DAK

BeitragFr, Okt 04, 2013 14:34
Antworten mit Zitat
Benutzer-Profile anzeigen
@BladeRunner:

Nö, tut es nicht. Super erlaubt es, geerbte Methoden aufzurufen, die durch lokale Methoden überschrieben werden. Siehe folgendes Beispiel:

BlitzMax: [AUSKLAPPEN]
SuperStrict
Framework BRL.StandardIO

Global test:String = "Global"

Type TParent
Field test:String = "Vererbt"

Method printTest(test:String)
Print(test)
Print(.test)
Print(Self.test)
End Method
End Type

Type TChild Extends TParent
Field test:String = "Field"

Method printTest(test:String)
Print(test)
Print(.test)
Print(Self.test)
End Method

Method printSuperTest(test:String)
Super.printTest(test)
End Method
End Type

Local child:TChild = New TChild

Print("NORMAL")
child.printTest("Parameter")
Print()
Print("SUPER")
child.printSuperTest("Parameter")



Würde man hier Super.test verwenden wollen, dann sagt einem der Compiler, dass das nicht geht.
Gewinner der 6. und der 68. BlitzCodeCompo

BladeRunner

Moderator

BeitragFr, Okt 04, 2013 16:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Oops, man verzeihe. da war der Blade irr. Ich sollte nicht aus dem Dienst heraus solche Dinge klären. Da ist die Birne zu Brei.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group