scala - implicito - discriminacion implicita
Cómo obtener la lista de métodos en Scala (6)
Ahora, espera un minuto.
Admito que Java es detallado en comparación con Ruby, por ejemplo.
Pero ese fragmento de código no debería haber sido tan detallado en primer lugar.
Aquí está el equivalente:
Collection<String> mds = new TreeSet<String>();
for( Method m : "".getClass().getMethods()) {
if( m.getName().matches(".*index.*")){ mds.add( m.getName() ); }
}
Que tiene casi la misma cantidad de caracteres que los marcados como correctos, versión Scala
En lenguaje como python y ruby, pregunte al lenguaje qué métodos relacionados con el índice admite su clase de cadena (los nombres de los métodos contienen la palabra "índice") que puede hacer.
“”.methods.sort.grep /index/i
Y en java
List results = new ArrayList();
Method[] methods = String.class.getMethods();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName().toLowerCase().indexOf(“index”) != -1) {
results.add(m.getName());
}
}
String[] names = (String[]) results.toArray();
Arrays.sort(names);
return names;
¿Cómo harías lo mismo en Scala?
Curioso que nadie haya intentado una traducción más directa:
""
.getClass.getMethods.map(_.getName) // methods
.sorted // sort
.filter(_ matches "(?i).*index.*") // grep /index/i
Por lo tanto, algunos pensamientos al azar.
La diferencia entre los "métodos" y los aros anteriores es sorprendente, pero nadie dijo que la reflexión fuera la fuerza de Java.
Estoy ocultando algo sobre lo
sorted
arriba: en realidad toma un parámetro implícito de tipoOrdering
. Si quisiera ordenar los métodos por sí mismos en lugar de sus nombres, tendría que proporcionarlos.Un
grep
es en realidad una combinación defilter
ymatches
. Se hizo un poco más complejo debido a la decisión de Java de hacer coincidir cadenas completas incluso cuando no se especifican^
y$
. Creo que sería sensato tener un métodogrep
enRegex
, que tomó como parámetro aTraversable
, pero ...
Entonces, esto es lo que podríamos hacer al respecto:
implicit def toMethods(obj: AnyRef) = new {
def methods = obj.getClass.getMethods.map(_.getName)
}
implicit def toGrep[T <% Traversable[String]](coll: T) = new {
def grep(pattern: String) = coll filter (pattern.r.findFirstIn(_) != None)
def grep(pattern: String, flags: String) = {
val regex = ("(?"+flags+")"+pattern).r
coll filter (regex.findFirstIn(_) != None)
}
}
Y ahora esto es posible:
"".methods.sorted grep ("index", "i")
El solo uso del código Java directo lo llevará a la mayor parte del camino, ya que las clases de Scala siguen siendo las de JVM. Sin embargo, también podría portar el código a Scala con bastante facilidad, por diversión / práctica / facilidad de uso en REPL.
Esto es hasta donde llegué:
"".getClass.getMethods.map(_.getName).filter( _.indexOf("in")>=0)
Es extraño que la matriz de Scala no tenga método de clasificación.
editar
Acabaría como.
"".getClass.getMethods.map(_.getName).toList.sort(_<_).filter(_.indexOf("index")>=0)
Más o menos de la misma manera:
val names = classOf[String].getMethods.toSeq.
filter(_.getName.toLowerCase().indexOf(“index”) != -1).
map(_.getName).
sort(((e1, e2) => (e1 compareTo e2) < 0))
Pero todo en una línea.
Para hacerlo más legible,
val names = for(val method <- classOf[String].getMethods.toSeq
if(method.getName.toLowerCase().indexOf("index") != -1))
yield { method.getName }
val sorted = names.sort(((e1, e2) => (e1 compareTo e2) < 0))
Puede utilizar el indicador de REPL de Scala. Para buscar enumerar los métodos de miembro de un objeto de cadena, por ejemplo, escriba "". y luego presione la tecla TAB (que es una cadena vacía, o incluso una que no está vacía, si lo desea, seguido de un punto y luego presione TAB). El REPL listará para usted todos los métodos de miembro.
Esto se aplica a otros tipos de variables también.