Jump to content
Rpg²S Forum

Annotazioni per meta-programmazione (simili a Java/C#)


Midi
 Share

Recommended Posts

Annotazioni per meta-programmazione

 

Descrizione

Script di utilità per scripters.

Permette di utilizzare delle annotazioni sui metodi di istanza, simili a quelle comunemente usate in Java e C#.

 

Autore

Jörg W Mittag (modifiche e istruzioni di Midi)

 

Allegati

Nessuno

 

Istruzioni per l'uso

Incollare lo script nella sezione "Materials", sopra il "Main" e sopra tutti gli script che si desidera annotare.

Le annotazioni vanno inserite prima dei metodi, indicate da un doppio comma (§§).

Maggiori dettagli nello script.

 

Script

 

 

#===============================================================================
# Java/C#-like Annotations
#===============================================================================
# by Jörg W Mittag
#    Midi
#-------------------------------------------------------------------------------
# Annotazioni per meta-programmazione sui metodi di istanza, con utilizzo e
# sintassi simili a quelle comunemente in uso per Java e C#.
#-------------------------------------------------------------------------------
# ISTRUZIONI
# Copiare questo script SOPRA TUTTI GLI SCRIPT che si vuole annotare.
#
# Per poter utilizzare le annotazioni, la classe deve chiamare il metodo
# "annotate!" prima di utilizzare le annotazioni (vedi esempio di sintassi).
#
# Le annotazioni sono indicate da un doppio comma (§§) all'inizio della stringa,
# immediatamente prima del metodo da annotare.
# Un metodo può avere un qualsiasi numero di annotazioni. Le annotazioni possono
# avere a loro volta un qualsiasi numero di parametri.
#-------------------------------------------------------------------------------
# SINTASSI (ESEMPIO):
# 
# class Classe_Annotata
#    annotate!
#    ...
#    §§annotazione_1
#    def metodo_annotato_1
#      ...
#    end
#
#    ...
#    §§annotazione_2(nome: "test")
#    §§annotazione_3 tipo: "prova", numero: 1
#    def metodo_annotato_2
#      ...
#
#    (eccetera)
#-------------------------------------------------------------------------------
# UTILIZZO
# Per richiamare le annotazioni relative a un metodo, chiamare il metodo di
# classe "annotations(simbolo_metodo)".
# Per esempio, utilizzando la classe annotata precedente:
#
#    Classe_Annotata.annotations(:metodo_annotato_2)
#
# restituirebbe:
#    {:annotazione_2 => {:nome => "test"},
#     :annotazione_3 => {:tipo => "prova", :numero => 1}}
# 
# Chiamando il metodo di classe "annotations" senza parametri, si ottengono
# tutte le annotazioni per quella classe:
#
#    Classe_Annotata.annotations
#
#===============================================================================
# Questo script è di Pubblico Dominio, e può quindi essere usato liberamente.
# La citazione dell'autore è gradita ma non obbligatoria.
#===============================================================================

module Annotations
  def annotations(meth = nil)
    return @__annotations__[meth] if meth
    @__annotations__
  end

  private

  def method_added(m)
    (@__annotations__ ||= {})[m] = @__last_annotation__ if @__last_annotation__
    @__last_annotation__ = nil
    super
  end

  def method_missing(meth, *args)
    return super unless /\A§§/ =~ meth
    @__last_annotation__ ||= {}
    @__last_annotation__[meth[2..-1].to_sym] = args.size == 1 ? args.first : args
  end
end

class Module
  private

  def annotate!
    extend Annotations
  end
end 

 

 

 

Bugs e Conflitti Noti

Nessuno

 

Altri dettagli

Lo script funziona anche per XP e VX.

Le istruzioni sono all'interno dello script.

Lo script è di pubblico dominio e quindi utilizzabile liberamente.

 

Esempio di utilizzo

Attualmente sto usando lo script per permettermi di identificare alcuni metodi, in modo tale che quando vengono chiamati possano essere eseguiti automaticamente altri metodi, senza doverli dichiarare all'interno dei metodi stessi.

È il principio della "programmazione ad aspetti".

 

Quindi, per esempio, invece di scrivere:

def metodo_che_necessita_pre_e_post_process
   pre_process
   (logica del metodo)
   post_process
end

grazie alle annotazioni scrivo:

§§state_process
def metodo_che_necessita_pre_e_post_process
  (logica del metodo...)
end

E alla fine, appena prima del Main, modifico in maniera dinamica tutti i metodi che presentano l'annotazione in questione.

 

In questo modo lascio pulita la logica del metodo, che risulta più leggibile e non include chiamate a codice che non c'entrerebbero nulla con lo scopo del metodo in questione.

 

Qui sotto spoiler il mio personale esempio di "modifica dinamica" dei metodi annotati, che ho inserito appena prima del Main.

 

 

$class_symbols = Object.constants.select {|c|
(Object.const_get(c).is_a? Class) }

for class_sym in $class_symbols
  clazz = eval(class_sym.to_s)
  next unless clazz.respond_to?("annotations")
  next unless clazz.annotations
  for meth in clazz.instance_methods
    method_name = meth.to_s
    methods_annotations = clazz.annotations(meth)
    next unless methods_annotations
    state_process_annotations = methods_annotations[:state_process]
    next unless state_process_annotations
    types = state_process_annotations[:types]
    next unless types
    eval %Q{
      class #{class_sym.to_s}
        alias midi_annotate_#{method_name} #{method_name}
        def #{method_name}(*args)
          new_args = pre_process(#{types}, "#{method_name}", *args)
          returned = midi_annotate_#{method_name}(*new_args)
          return post_process(returned, #{types}, "#{method_name}", *new_args)
        end
      end
    }
  end
end 

 

 

Edited by Midi

Aurora Dreaming


The Dreamer (v. 1.1) - standalone


72 MB - Il prequel ad Aurora Dreaming



segui il dev-diary ufficiale di Aurora Dreaming!



Bacheca Premi


http://www.rpg2s.net/forum/uploads/monthly_01_2014/post-6-0-39588100-1390575633.png

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...