Domanda

Stiamo cercando di costruire un'API per il supporto commit () e rollback () in modo automatico, in modo da non dover perdere tempo con più. Con la ricerca, abbiamo trovato che l'uso eval {} è la strada da percorrere.

Per eval {} per sapere cosa fare, ho pensato di dare l'API una serie di funzioni, che si può eseguire con un foreach senza l'API dover intepret nulla. Tuttavia, questa funzione potrebbe essere in un pacchetto differente.

Vorrei chiarire con un esempio:

sub handler {
    use OSA::SQL;
    use OSA::ourAPI;
    my @functions = ();
    push(@functions, OSA::SQL->add_page($date, $stuff, $foo, $bar));
    my $API = OSA::ourAPI->connect();
    $API->exec_multi(@functions);
}

La domanda è: E 'possibile eseguire le funzioni in @functions all'interno di OSA::ourAPI, anche se non ha ourAPI use OSA::SQL. In caso contrario, sarebbe possibile se uso un riferimento matrice anziché una matrice, visto che il puntatore indicherebbe la funzione nota all'interno della memoria?

Nota: Questa è l'idea di base che vogliamo basare la versione finale più complesso il

.
È stato utile?

Soluzione


  • Stai non aggiungere un puntatore a funzione per l'array. Si sta aggiungendo teh valore di ritorno di chiamare la subroutine add_page (). Hai 3 soluzioni a questo:

    A. Sarà necessario memorizzare (in @functions) una serie di arrayrefs della forma [\&OSA::SQL::add_page, @argument_values], il che significa che si passa in un riferimento reale per una subroutine (chiamato in modo statico); e poi exec_multi farà qualcosa di simile (sintassi potrebbero non essere corretta al 100% in quanto di 04:00 qui)

    sub exec_multi {
        my ($class, $funcs)= @_;
        foreach my $f (@$funcs) {
            my ($func, @args) = @$f;
            my $res = &$func(@args);
            print "RES:$res\n";
        }
    }
    

    Solo per ribadire, questa chiamerà singoli sottotitoli nella versione statica (OSA::SQL::add_page), ad esempio Senza far passare il nome del pacchetto come primo parametro come OSA::SQL->add_page chiamata classe sarebbe. Se si desidera che il secondo, vedere la soluzione successiva.


    B. Se si desidera chiamare i tuoi sottotitoli in contesto di classe (come nel tuo esempio, in altre parole con il nome della classe come primo parametro), è possibile utilizzare il suggerimento di ysth nel commento.

    È necessario memorizzare (in @functions) una serie di arrayrefs della forma [sub { OSA::SQL->add_page(@argument_values) }], il che significa che si passa in un riferimento ad una subroutine che sarà a sua volta chiamata che cosa avete bisogno; e poi exec_multi farà qualcosa di simile (sintassi potrebbero non essere corretta al 100% in quanto di 04:00 qui)

    sub exec_multi {
        my ($class, $funcs)= @_;
        foreach my $f (@$funcs) {
            my ($func) = @$f;
            my $res = &$func();
            print "RES:$res\n";
        }
    }
    

    C. Sarà necessario memorizzare (in @functions) una serie di arrayrefs della forma [ "OSA::SQL", "add_page", @argument_values], il che significa che si passa in un nome di pacchetto e la funzione; e poi exec_multi farà qualcosa di simile (sintassi potrebbero non essere corretta al 100% in quanto di 04:00 qui)

    my ($package, $sub, @args) = @{ $functions[$i] };
    no strict 'refs';
    $package->$sub(@args);
    use strict 'refs';
    

  • Se ho capito la tua domanda correttamente, allora non c'è bisogno di preoccuparsi se ourAPI utilizza OSA :: SQL, poiché i vostri principali importazioni di codice già.

    Tuttavia, dal momento che - a # 1B - si passerà una lista di pacchetti per exec_multi come primi elementi di ogni rifarray, si può fare "require $package; $package->import();" in exec_multi. Ma ancora una volta, è completamente non necessarie se la chiamata del gestore già richiesto e caricato ciascuno di questi pacchetti. E per farlo bene è necessario passare in un elenco di parametri per import() pure. MA WHYYYYYY? :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top