This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Ruby-like method reflection for Scala

2 replies
Tyler Jennings
Joined: 2009-05-01,
User offline. Last seen 42 years 45 weeks ago.

Hello,

New to the list, glad to be here. I'm coming to Scala from Ruby and I
discovered quite quickly how much I missed Ruby's simple reflection
mechanism which goes something like this:

>> "A String".methods.sort
=> ["%", "*", "+", "<", "<<", "<=", "<=>", "==", "===", "=~", ">",
">=", "[]", "[]=", "__id__", "__send__" ...

I've found its absence to be a great impediment to me learning Scala,
so I took a crack at implementing it using Java's reflection API (I
was a Java guy before I was a Ruby guy). The usage looks like this:

scala> namesOf(methods("a String"))
res0: String = charAt, codePointAt, codePointBefore, codePointCount,
compareTo ...

scala> signaturesOf(methods("a String"))
res1: String = charAt(int): char, codePointAt(int): int,
codePointBefore(int): int

The source is available here:
http://github.com/tjennings/Tyler-s-Scala-Extensions/tree/master

First, I would like to get your feedback on this. Can I do it better?
My first implementation used an implicit conversion to AnyRef, but I
decided it was too dangerous due to potential conflicts.

Second, the REPL truncates responses which makes this tool less
useful. What can I do about that?

Third, is there a way to have useful libs like this loaded into the
REPL automatically?

cheers,

-Tyler Jennings

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Ruby-like method reflection for Scala

On Thu, Apr 30, 2009 at 10:33:20PM -0500, Tyler Jennings wrote:
> >> "A String".methods.sort
> => ["%", "*", "+", "<", "<<", "<=", "<=>", "==", "===", "=~", ">",
> ">=", "[]", "[]=", "__id__", "__send__" ...

If you use trunk all this info is available via tab completion (although
it doesn't work on literals yet, so "abc". doesn't do it.)

scala> val x = "abc"
x: java.lang.String = abc

scala> x.

asInstanceOf charAt codePointAt
codePointBefore codePointCount compareTo
compareToIgnoreCase concat contains
contentEquals endsWith equalsIgnoreCase
[etc]

scala> x.getClass
res3: java.lang.Class[_ <: java.lang.Object] = class java.lang.String

scala> res3.

asInstanceOf asSubclass cast desiredAssertionStatus
getAnnotation getAnnotations getCanonicalName getClass
[etc]

> My first implementation used an implicit conversion to AnyRef, but I
> decided it was too dangerous due to potential conflicts.

That's your ruby lizard brain, trying to mislead you! In ruby it's
dangerous bceause it'll break at runtime. In scala it's really not (or
at least much less so) because if there is a conflict it won't compile.
Go ahead and implicitly convert to AnyRef, we all do it eventually.

> Second, the REPL truncates responses which makes this tool less
> useful. What can I do about that?

There's a secret val called settings which you can tweak.

scala> settings
res0: scala.tools.nsc.InterpreterSettings =
InterpreterSettings {
maxPrintString = 390
}
scala> settings.maxPrintString = 5000

> Third, is there a way to have useful libs like this loaded into the
> REPL automatically?

alias repl='scala -i my_file_of_scala_stuff.scala'

Tyler Jennings
Joined: 2009-05-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Ruby-like method reflection for Scala

All great advice, just what I wanted to know. Thank you. I'll keep
working on the ruby lizard brain =].

> If you use trunk all this info is available via tab completion (although
> it doesn't work on literals yet, so "abc". doesn't do it.)

That's what I really wanted to hear! And less typing! Bill Venners
told me exactly that on twitter today, but I didn't process it
correctly.

-Tyler

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland