J'avais besoin d'un exemple quelconque pour tester différentes choses en Kotlin, dont :
- L'internationalisation
- La surcharge des opérateurs
- L'utilisation de dépendances et de libs Java
Et comme c'est la mode de faire des clones de Tap Tempo, ça me paraissait être un bon candidat. Donc voici le mien – en Kotlin, donc. Il me parait être plus dans l'esprit de la version d'origine que la version Java (qui elle aussi tourne sur une JVM).
Pour vous éviter de fouiller, voici le code source du seul fichier avec de la logique dedans :
package fr.spacefox.kotaten
import com.beust.jcommander.*
import com.beust.jcommander.validators.PositiveInteger
import com.google.common.collect.EvictingQueue
import java.text.DecimalFormat
import java.text.MessageFormat
import java.util.*
import java.util.ResourceBundle
private const val NS_PER_SECOND = 1_000_000_000L
private const val PRECISION_DEFAULT = 0
private const val PRECISION_MIN = 0
private const val PRECISION_MAX = 0
private const val RESET_TIMER_DEFAULT = 5L
private const val SAMPLE_SIZE_DEFAULT = 5
private fun Double.toBpm(): Double {
return 60.0 * 1_000_000_000 / this
}
private operator fun ResourceBundle.get(key: String): String {
return this.getString(key)
}
@Parameters(resourceBundle = "messages")
class Settings {
@Parameter(names = ["-h", "--help"], descriptionKey = "options.help", help = true)
var help = false
@Parameter(
names = ["-p", "--precision"],
descriptionKey = "options.precision",
validateWith = [PrecisionValidator::class])
var precision = PRECISION_DEFAULT
@Parameter(
names = ["-r", "--reset-time"],
descriptionKey = "options.resettime",
validateWith = [PositiveInteger::class])
var resetTime = RESET_TIMER_DEFAULT
@Parameter(
names = ["-s", "--sample-size"],
descriptionKey = "options.samplesize",
validateWith = [PositiveInteger::class])
var sampleSize = SAMPLE_SIZE_DEFAULT
@Parameter(names = ["-v", "--version"], descriptionKey = "options.version")
var version = false
class PrecisionValidator: IParameterValidator {
override fun validate(name: String?, value: String?) {
val precision = Integer.parseInt(value)
if (precision < PRECISION_MIN || precision > PRECISION_MAX) {
throw ParameterException(MessageFormat.format(
ResourceBundle.getBundle("messages")["options.precision.outofscope"],
PRECISION_MIN,
PRECISION_MAX,
precision))
}
}
}
}
class Kotaten(settings: Settings) {
private val input = Scanner(System.`in`)
private val samples: EvictingQueue<Long> = EvictingQueue.create<Long>(settings.sampleSize)
private val messages = ResourceBundle.getBundle("messages")
private val formatter = DecimalFormat()
private val resetTime = settings.resetTime * NS_PER_SECOND
init {
input.useDelimiter("")
formatter.minimumFractionDigits = settings.precision
formatter.maximumFractionDigits = settings.precision
}
fun run() {
println(messages["instructions"])
var key: Char
var start: Long? = null
var end: Long
while (input.hasNext()) {
key = input.next()[0]
if (key == 'q')
break
end = System.nanoTime()
if (start == null || (end - start) > resetTime) {
samples.clear()
println(messages["typeagain"])
} else {
samples.add(end - start)
}
start = end
if (samples.size > 0)
print(MessageFormat.format(
messages["tempo"],
formatter.format(samples.average().toBpm())))
}
println(messages.getString("bye"))
}
}
fun main(args: Array<String>) {
val settings = Settings()
val jc = JCommander.newBuilder()
.addObject(settings)
.build()
jc.parse(*args)
if (settings.help) {
jc.usage()
return
}
if (settings.version) {
println(ResourceBundle.getBundle("config")["version"])
return
}
Kotaten(settings).run()
}
# Vraie app
Posté par ʭ ☯ . Évalué à 3.
J'adore. Plus qu'à ajouter une commande du flash pour faire clignoter le flash au rythme du tempo. C'est la fête!
⚓ À g'Auch TOUTE! http://afdgauch.online.fr
# Java ?
Posté par mzf (site web personnel) . Évalué à 1.
J'ai du mal à comprendre la relation du Kotlin avec le Java. Le langage est interprété par une JVM ? et on peut utiliser directement d'autres modules java ?
Si oui, quel est son intérêt ? moins verbeux ?
(et merci pour cette version !)
[^] # Re: Java ?
Posté par groumly . Évalué à 4.
Le langage est compilé directement en bytecode, donc exécuté par la jvm comme du java, ou tout autre langage jvm (clojure, scala etc).
100% compatible avec java (y compris les annotations par exemple).
L’interet C’est des feature plus moderne (first class support des optional), et vachement vachement moins verbeux.
C’est en gros comme java, mais largement modernisé.
Linuxfr, le portail francais du logiciel libre et du neo nazisme.
[^] # Re: Java ?
Posté par SpaceFox (site web personnel, Mastodon) . Évalué à 2.
groumly a bien résumé. En gros, Kotlin c'est le résultat des développeurs d'IntelliJ qui se sont dit « Il nous faut un langage compatible avec Java sur la JVM, mais plus simple, plus moderne, et avec des améliorations orientées pragmatiquement pour les développeurs ».
Plus d'infos :
La connaissance libre : https://zestedesavoir.com
# Conversion automatique de code
Posté par SpaceFox (site web personnel, Mastodon) . Évalué à 4.
À noter que Kotlin (enfin, au moins IntelliJ) permet de convertir du code Java en Kotlin. Ça fonctionne, mais nécessite un peu de nettoyage et de « Kotlinisation » du code.
Par exemple, si je convertis le TapTempo Java directement, j'obtiens (après avoir remis les fonctions directement dans le fichier, sans passer par un objet inutile) :
Bref, c'est surtout utile pour :
La connaissance libre : https://zestedesavoir.com
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.