2011-01-17 16 views
41

Oltre all'integrazione con linguaggi dinamici sulla JVM, quali sono gli altri potenti utilizzi di uno Dynamic type in un linguaggio tipizzato in modo statico come Scala?Uso pratico di un tipo dinamico in Scala

+1

Senza supporto lingua (ad es. 'dynamic' in C# .4), in realtà non" vedo "cosa sta succedendo con quel commit. Sarebbe interessante vedere come si adatta. –

+1

Le risposte a questa domanda sono estremamente obsolete, per le risposte effettive si veda: [Come funziona Dynamic lavorare e come usarlo?] (Http://stackoverflow.com/q/15799811/465304) – sschaef

risposta

21

Suppongo che un tipo dinamico possa essere utilizzato per implementare molte delle funzionalità presenti in JRuby, Groovy o altri linguaggi JVM dinamici, come metaprogrammazione dinamica e method_missing.

Ad esempio, creando una query dinamica simile a Record attivo in Rails, in cui un nome di metodo con parametri viene convertito in una query SQL in background. Questo sta utilizzando la funzionalità method_missing in Ruby. Qualcosa di simile (in teoria - non hanno cercato di implementare qualcosa di simile):

class Person(val id: Int) extends Dynamic { 
    def _select_(name: String) = { 
    val sql = "select " + name + " from Person where id = " id; 
    // run sql and return result 
    } 

    def _invoke_(name: String)(args: Any*) = { 
    val Pattern = "(findBy[a-zA-Z])".r 
    val sql = name match { 
     case Pattern(col) => "select * from Person where " + col + "='" args(0) + "'" 
     case ... 
    } 
    // run sql and return result 
    } 
} 

Permettere l'utilizzo come questo, in cui è possibile chiamare i metodi 'nome' e 'findByName' senza dover esplicitamente definite nella classe Person :

val person = new Person(1) 

// select name from Person where id = 1 
val name = person.name 

// select * from Person where name = 'Bob' 
val person2 = person.findByName("Bob") 

Se è stato da aggiungere metaprogrammazione dinamica, il tipo dinamico sarebbe necessaria per consentire invocare i metodi che sono stati aggiunti durante l'esecuzione ..

+0

Nel terzo esempio non si utilizza maiuscola P: 'Person.findByName (" Bob ")'? – anishpatel

2

si potrebbe anche usarlo per lo zucchero sintattico sulle mappe:

class DynamicMap[K, V] extends Dynamic { 
    val self = scala.collection.mutable.Map[K, V]() 
    def _select_(key: String) = self.apply(key) 
    def _invoke_(key: String)(value: Any*) = 
    if (value.nonEmpty) self.update(key, value(0).asInstanceOf[V]) 
    else throw new IllegalArgumentException 
} 

val map = new DynamicMap[String, String]() 

map.foo("bar") // adds key "foo" with value "bar"  
map.foo   // returns "bar" 

Per essere onesti questo si salva solo un paio di sequenze di tasti da:

val map = new Map[String, String]() 
map("foo") = "bar" 
map("foo") 
+1

Si noti che questo esempio non funziona per un paio di motivi, ma non penso che ci sia molto da fare esplorando ulteriormente prima che la funzione sia più stabile. –

+0

L'ho fatto funzionare qui: [http://stackoverflow.com/questions/14876856/simple-scala-macro] –