- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Ruby-like method reflection for Scala
Fri, 2009-05-01, 04:33
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
Fri, 2009-05-01, 05:37
#2
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
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'