Στη Μ2000 τα αντικείμενα λέγονται ομάδες και μπορούν να έχουν μεταβλητές, συναρτήσεις, τμήματα, πίνακες, και άλλες ομάδες. Αυτό που δεν έχουν άμεσα είναι μεταβλητές κλάσης. Επειδή μια κλάση είναι μια συνάρτηση που επιστρέφει μια ομάδα δεν έχει να κάνει με κάποια λίστα καταγραφής. Η κάθε ομάδα που φτιάχνουμε έχει τη δική της λίστα με το τι περιέχει.
Μάλιστα μια ομάδα με όνομα έχει κάθε στοιχείο της ως μεταβλητή του τμήματος, κυριολεκτικά. Με την εντολή Λίστα θα δούμε όλα τα στοιχεία με πρόθεμα το όνομα της ομάδας, και ένα στοιχείο ξέχωρο το αντικείμενο με το όνομα. Αυτό κρατάει μια λίστα που χρειάζεται για να περνάμε με αναφορά ή με αντιγραφή την ομάδα σε συναρτήσεις/τμήματα/σωρό.
Σε μια ομάδα με όνομα δεν μπορούμε να διαγράψουμε στοιχεία!Με το που φτιάχνονται τα στοιχεία μπαίνουν στην λίστα του τμήματος. Μπορούμε να χρησιμοποιήσουμε το Για ΌνομαΟμάδας { } ώστε να ανοίξουμε ένα μπλοκ για προσωρινές αλλαγές στη λίστα στοιχείων του τμήματος, που σημαίνει ότι μπορούμε πρόσκαιρα να έχουμε μεταβλητές στην ομάδα, αλλά εδώ δεν θα επεκταθούμε σε αυτό. Θα δούμε δηλαδή μια πιο κανονική προσέγγιση. Αυτό που σίγουρα θα έχουμε δει και σε άλλες αναρτήσεις σε αυτό το blog είναι ότι μπορούμε να προσθέτουμε στοιχεία, ή και να αλλάζουμε διαστάσεις στους πίνακες, ή και να αλλάζουμε ορισμούς στα τμήματα και στις συναρτήσεις.
Επιπλέον έχουμε δει και ότι το "=" μεταξύ δυο ομάδων (έστω Α και Β είναι ομάδες) όπως το Α=Β δεν θα κάνει το Α ίσο με το Β αλλά θα βάλει τα στοιχεία του Β στο Α και όσα έχουν ίδιο όνομα θα αλλάξουν. Που σημαίνει ότι κάνουμε ένωση.
Εδώ πρέπει να ξεχωρίσουμε την περίπτωση που έχουμε κλειστές ομάδες. Σε στοιχεία πίνακα μπορούμε να έχουμε μόνο κλειστές ομάδες. Λέγονται κλειστές γιατί δεν "ανιχνεύονται", δεν έχουν τα στοιχεία τους στη λίστα στοιχείων του τμήματος που βρίσκονται (είναι πραγματικά encapsulated). Στις κλειστές ομάδες και όσο είναι κλειστές γίνεται αντικατάσταση, Δηλαδή χάνεται το παλιό και στη θέση του μπαίνει το νέο. Δεν υπάρχουν ενεργές αναφορές στα αντικείμενα της Μ2000. Οι αναφορές υπάρχουν εκεί που εκτελείται κώδικας. Αντίθετα μπορούμε να κρατάμε ισχνές αναφορές. Δηλαδή μισές αναφορές, οι οποίες ενδέχεται να μην δείχνουν σε υπάρχον στοιχείο. Εδώ δεν έχουμε θέμα με διευθύνσεις. Οι ισχνές αναφορές έχουν ονόματα, οπότε η χρήση τους είναι θέμα του προγραμματιστή.
Σύντομη περιγραφή με τη χρήση (δείτε πως η Α$ μπορεί να αλλάζει, να δείχνει κάτι άλλο)
Χρησιμοποιούνται οι Weak$() που φτιάχνει το δείκτη, η Eval() για αριθμητικές παραστάσεις (Από αλφαριθμητικό). η Eval$() για αλφαριθμητικές παραστάσεις με δείκτες - και χωρίς- η Function() καθώς και αυτή που δεν φαίνεται η Function$() για συναρτήσεις που γυρνάνε αλφαριθμητικά.
Ο διερμηνευτής βρίσκει ότι κάτι έχει δείκτη από το ζευγάρι αυτό $. (δεν υπάρχει περίπτωση κάπου αλλού να έχουμε το δολάριο και την τελεία μαζί). Μόνο στην Eval όταν το αποτέλεσμα είναι αλφαριθμητικό - ενώ ζητάμε αριθμό υπολογίζεται για δείκτης.
Πρόσθεσα και παράδειγμα με τα Array() και Array$() για πίνακες και ισχνές αναφορές.
k=10
A$=Weak$(k)
A$.+=20
Print Eval(A$.) ' 30
Print Eval(A$) ' we can exclude right dot
B$="George"
A$=Weak$(B$)
Print Eval$(A$.) \\ look the dot right
Print Eval$(A$) \\ now we get the pointer (not the value from pointer)
A$.="Hello"
Print Eval$(A$.) \\ Hello
Print B$ \\ Hello
Group Alfa {
X=10
Function X2 { =.X**2+Number}
Module XX {Print "ok", .X }
}
A$=Weak$(Alfa)
A$.X++
Print Eval(A$.X) ' 11
Print Function(A$.X2,20) ' 141
A$.XX ' print: ok 11
Dim A(10,3)=20, B$(4)="ok"
A$=Weak$(A())
Print Array(A$, 3,2) ' 20
A$=Weak$(B$())
Print Array$(A$, 3) 'ok
Πάνω λοιπόν στις ισχνές αναφορές δουλεύει και το παρακάτω παράδειγμα. Εδώ σκοπός μας είναι να βάλουμε σε μια ομάδα εκ των υστέρων (υπάρχει δηλαδή η ομάδα) σύνδεση με μια γενική (Global), μια τοπική αριθμητική και μια τοπική αλφαριθμητική, όπου όλες θα φαίνονται μέσα σε όλες τις ομάδες που θα φτιάξουμε με την αρχική. Για να πετύχουμε περισσότερα έχουμε φτιάξει μια συνάρτηση την Pass3group η οποία παίρνει το όνομα που θα θέλαμε να έχει μια μεταβλητή που την περνάμε με ισχνή αναφορά (και με πέρασμα &kl$ περνάμε ισχνή αναφορά. Σημασία έχει αν από την πλευρά της συνάρτησης η Διάβασε διαβάζει αλφαριθμητικό ή διαβάζει αναφορά με &. Αν κάνει το δεύτερο τότε φτιάχνει κανονική αναφορά, εμείς εδώ κάνουμε το πρώτο, διαβάζουμε αλφαριθμητικό, άρα την ισχνή αναφορά. (δες την μεταβλητή var$).
Αφού φτιάξουμε τις τρεις μεταβλητές, δούμε πως τις αλλάζουμε, πως τις διαβάζουμε, μετά αντιγράφουμε σε μια επώνυμη ομάδα και μετά σε μια κλειστή σε πίνακα. Επίσης περνάμε τον πίνακα με αναφορά σε ένα τμήμα και βλέπουμε ότι λειτουργούν όλα καλά!
Όμως όλο σχεδόν το παράδειγμα έγινε σε ένα CheckAll για να δούμε την επιστροφή του πίνακα ομάδων που κάνουμε με την Βάλε (Push) στο σωρό τιμών. Με το που επιστρέφουμε από το τμήμα (το είχαμε καλέσει με Call ή Κάλεσε αλλά δεν χρειάζονταν ιδιαίτερα, θα μπορούσαμε να το παραλείψουμε), διαβάζουμε από το σωρό τον πίνακα (σε ένα στοιχείο του σωρού ήταν όλος ο πίνακας). Τώρα δοκιμάζουμε τα Exist...για να δούμε αν τι έχουμε (μόνο βέβαια την γενική MyVar)
Global myvar=100
Module CheckAll {
\\ This function construct variables with weak reference to globals or locals
\\ And return a group for union
\\ Make the variable as a string contains weak reference
\\ We make GetVar() function, SetVar module and ExistVar() function
Function Pass2group {
Read name$, var$
if Right$(var$,1)="$" then {
name$=Filter$(name$,"$")
template$={
glob{0}$="{1}"
Function Get{0}$ %%=Eval$(.glob{0}$.)||
Module Set{0} %%.glob{0}$.<=Letter$ ||
Function Exist{0} %% =Valid(Eval$(.glob{0}$.)="")||
}
} else {
template$={
glob{0}$="{1}"
Function Get{0} %%=Eval(.glob{0}$)||
Module Set{0} %%.glob{0}$.<=Number||
Function Exist{0} %% =Valid(Eval(.glob{0}$))||
}
}
template$=format$(template$,name$, var$)
template$=replace$("%%","{",template$)
template$=replace$("||","}",template$)
group aa type template$
=aa
}
Group AA {
M=10
}
\\ we add a global
AA=Pass2group("X", Weak$(myvar))
Print AA.GetX()
AA.SetX 123
Print AA.GetX()
alfa=1000
\\ we add a local
AA=Pass2group("Y", Weak$(alfa))
Print AA.GetY()
kl$="Ok"
\\ we add a local string
AA=Pass2group("K$", Weak$(kl$))
Print AA.GetK$()
AA.SetK "Hello There"
Print AA.GetK$()
Dim Alfa(10)=AA
Print Alfa(2).GetK$()
Alfa(5).SetK "Change it" ' change to Alfa(5) also change for all
Print Alfa(2).GetK$()
Module CheckMe {
Read &All()
For All(4) {
Print .GetX(), .GetY(), .GetK$()
.SetY 500 ' we set alfa in module
}
Print All(9).ExistY() ' -1
}
CheckMe &Alfa()
Print alfa ' 500
Push Alfa() \\ export array from module
}
Call CheckAll
Read AA()
Print AA(2).ExistY() ' 0 no not now
Print AA(3).M ' Only M exist and...
Print AA(4).ExistX() ' X as global MyVar
Print AA(4).GetX()
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.