Τρίτη, 2 Ιουνίου 2015

Ενσωμάτωση delegate functions στην Μ2000

Πολύ καλή αναθεώρηση της Μ2000. προστέθηκαν ωραία πράγματα

Παρακάτω είναι η δική μου έκδοση ενός παραδείγματος που υπάρχει σε C# (δείτε εδώ). Κατάφερα να αυξήσω τις δυνατότητες των ομάδων της Μ2000, ώστε να μπορούν να δέχονται μια ομάδα από την οποία καλούν μια συγκεκριμένη συνάρτηση και περνούν μια αναφορά της ομάδας ώστε αυτή η συνάρτηση να κάνει κάποιες αλλαγές ή πράξεις γενικότερα. Μπορούμε να δίνουμε άλλες ομάδες με ίδια συνάρτηση μόνο στο όνομα...αλλά όχι στη λειτουργικότητα. Αυτές οι συναρτήσεις λέγονται delegates.

Το πρόγραμμα το έχω γράψει στα αγγλικά (η Μ2000 τρέχει στα ελληνικά και στα αγγλικά, έχει διπλό λεξιλόγιο). Χρησιμοποιεί τέσσερις ομάδες: PrintTitle, PriceTotaller, bookDB, SecondbookDB. Τα δυο τελευταία τα φτιάχνουμε με το booktype$, ένα αλφαριθμητικό, δηλαδή δίνουμε έμμεσα ορισμό.

Στη Μ2000 δεν υπάρχουν αντικείμενα, αλλά ομάδες Μια ομάδα μπορεί να περάσει με αναφορά (και ό,τι ορίζουμε τοπικό δεν θα είναι προσβάσιμο μέσω της αναφοράς). Αυτό γίνονταν και πριν, αλλά δεν γίνονταν μια μέθοδος ή μια συνάρτηση μιας ομάδας να περάσει τον εαυτό της με αναφορά. Επιπλέον έγιναν πολλές διορθώσεις και προστέθηκε η εντολή φόρμα$() ή format$() δείτε την παρακάτω, και η πολύ καλή "Για"με όνομα ομάδας μόνο. Την χρησιμοποιώ εδώ κατά κόρο. π.χ.
αντί να γράψω αυτό
      call SecondbookDB.ProcessPaperbackBooks &PriceTotaller
γράφω αυτό, και όπου υπάρχει μια τελεία προστίθεται το SecondbookDB
for SecondbookDB {
      call .ProcessPaperbackBooks &PriceTotaller
}
Μπορούμε να έχουμε φωλιασμένα Για και στο εσωτερικό, έστω δεύτερο θα έχουμε αναφορά με διπλή τελεία, στο τρίτο εσωτερικό με τρεις...
Δείτε εδώ η p(i) έχει δυο τελείες, και αναφέρεται στο Anybook, ενώ η total έχει μια και αναφέρεται στο τρέχον (το αυτό ή this στα αγγλικά).
   function processBook { read &AnyBook, i : for this {.items++ : for Anybook {.total+=..p(i)  } }}



\\ Παράδειγμα με delegate functions
booktype$={
      local countme=0
      dim t$(1), a$(1), p(1), pb(1)
      function AddBook {
            for this {
                  newdim =.countme+1
                  dim .t$(newdim), .a$(newdim), .p(newdim), .pb(newdim)      
                  read .t$(.countme), .a$(.countme), .p(.countme), .pb(.countme)
                  .countme++
            }
      }
      module ProcessPaperbackBooks {
            read &ProcessBookDelegate
                  for this {
                        if .countme<1 then exit
                        for i=0 to .countme-1 {
                              if .pb(i) then call ProcessBookDelegate.processBook(&this, i)
                        }
                  }
      }
}
group PrintTitle {
      function processBook { read &AnyBook, i : Report format$("    {0}", AnyBook.t$(i) )}
}
group PriceTotaller {
      local items, total
      function processBook { read &AnyBook, i : for this {.items++ : for Anybook {.total+=..p(i) } }}
      \\  look the <= operator, if we use = then we define local variables. Items and total are like global but for group only
      module zero { for this { .total<=0 : .items<=0 } }
      function AveragePrice { for this {if .items>0 then =.total/.items }}
}
group bookDB type booktype$
report "First Book DB"
for bookDB {
      call .AddBook("The C Programming Language", "Brian W. Kernighan and Dennis M. Ritchie", 19.95, true)
      call .AddBook("The Unicode Standard 2.0", "The Unicode Consortium", 39.95, true)
      call .AddBook("The MS-DOS Encyclopedia", "Ray Duncan", 129.95, false)
      call .AddBook("Dogbert's Clues for the Clueless", "Scott Adams", 12.00, true)
      call .ProcessPaperbackBooks &PriceTotaller
      report  "Average Paperback Book Price: $" + str$(PriceTotaller.AveragePrice(),"#.##")
      call .ProcessPaperbackBooks &PrintTitle
}
report "Second Book DB"    \\report prints text  proportionally with justification
PriceTotaller.zero
group SecondbookDB type booktype$
for SecondbookDB {
      call .AddBook("Any Big Big and Big Tilte", "Any Author", 3.45, true)
      call .ProcessPaperbackBooks &PriceTotaller
      report  "Average Paperback Book Price: $" + str$(PriceTotaller.AveragePrice(),"#.##")
      call .ProcessPaperbackBooks &PrintTitle
}

Αυτή είναι η έξοδος!



Το παραπάνω τρέχει ως έχει και στην Έκδοση 8, αλλά τρέχει και έτσι! (με την εντολή Class ή Κλάση)


class booktype {
      local countme=0
      dim t$(), a$(), p(), pb()
      module AddBook {
                  newdim =.countme+1
                  dim .t$(newdim), .a$(newdim), .p(newdim), .pb(newdim)
                  read .t$(.countme), .a$(.countme), .p(.countme), .pb(.countme)
                  .countme++
      }
      module ProcessPaperbackBooks {
            read &AnyFunction()
            if .countme<1 then exit
            for i=0 to .countme-1 {
                  if .pb(i) then call AnyFunction(&this, i)
            }
      }
}
function PrintTitle {
      read &AnyBook, i : Report format$("    {0}", AnyBook.t$(i) )
}
class PriceTotaller {
      local items, total
      function processBook { read &AnyBook, i : for this {.items++ : for Anybook {.total+=..p(i) } }}
      module zero { .total<=0 : .items<=0 }
      function AveragePrice { if .items>0 then =.total/.items }
}
bookDB=booktype()
PriceTotaller1=PriceTotaller()
report "First Book DB"
for bookDB {
      .AddBook"The C Programming Language",  "Brian W. Kernighan and Dennis M. Ritchie", 19.95, true
      .AddBook"The Unicode Standard 2.0",  "The Unicode Consortium", 39.95, true
      .AddBook"The MS-DOS Encyclopedia", "Ray Duncan", 129.95, false
      .AddBook"Dogbert's Clues for the Clueless", "Scott Adams", 12.00, true
      .ProcessPaperbackBooks &PriceTotaller1.processBook()
      report  "Average Paperback Book Price: $" + str$(PriceTotaller1.AveragePrice(),"#.##")
      .ProcessPaperbackBooks &PrintTitle()
}
report "Second Book DB"   
PriceTotaller2=PriceTotaller()
SecondbookDB=booktype()
for SecondbookDB {
      .AddBook "Any Big Big and Big Tilte",  "Any Author", 3.45, true
      .ProcessPaperbackBooks &PriceTotaller2.processBook()
      report  "Average Paperback Book Price: $" + str$(PriceTotaller2.AveragePrice(),"#.##")
      .ProcessPaperbackBooks &PrintTitle()
}