I have been trying to use scala.util.parsing.combinator.lexical.StdLexical but I'm not sure how to do it. I have been trying like this:
import scala.util.parsing.combinator.lexical.StdLexical
class Foo extends StdLexical {
def main(args: Array[String]) {
val input = """
class Main {
def main(args: Array[String]) {
println("hello world")
}
}
"""
val scanner = new Scanner(input)
println(scanner.first)
}
}
It compiles and runs but nothing is printed. Can anyone give me a simple example using this class? (Preferably I want to get all the tokens at once in a list or similar)
You don't get any output because you use class instead of object, thus your code is never executed.
To get all token, you must fetch them manually:
def loop(s: Scanner, token: Seq[Token]): Seq[Token] =
if (s.atEnd) token
else loop(s.rest, token :+ s.first)
println(loop(new Scanner(input), Vector()))
Nevertheless, StdLexical doesn't tokenise the complete Scala grammar. If you need this, I suggest to use Scalariform and its tokenise method.
Related
I am working on a scripted Jenkins-Pipeline that needs to write a String with a certain encoding to a file as in the following example:
class Logger implements Closeable {
private final PrintWriter writer
[...]
Logger() {
FileWriter fw = new FileWriter(file, true)
BufferedWriter bw = new BufferedWriter(fw)
this.writer = new PrintWriter(bw)
}
def log(String msg) {
try {
writer.println(msg)
[...]
} catch (e) {
[...]
}
}
}
The above code doesn't work since PrintWriter ist not serializable so I know I got to prevent some of the code from being CPS-transformed. I don't have an idea on how to do so, though, since as far as I know the #NonCPS annotation can only be applied to methods.
I know that one solution would be to move all output-related code to log(msg) and annotate the method but this way I would have to create a new writer every time the method gets called.
Does someone have an idea on how I could fix my code instead?
Thanks in advance!
Here is a way to make this work using a log function that is defined in a shared library in vars\log.groovy:
import java.io.FileWriter
import java.io.BufferedWriter
import java.io.PrintWriter
// The annotated variable will become a private field of the script class.
#groovy.transform.Field
PrintWriter writer = null
void call( String msg ) {
if( ! writer ) {
def fw = new FileWriter(file, true)
def bw = new BufferedWriter(fw)
writer = new PrintWriter(bw)
}
try {
writer.println(msg)
[...]
} catch (e) {
[...]
}
}
After all, scripts in the vars folder are instanciated as singleton classes, which is perfectly suited for a logger. This works even without #NonCPS annotation.
Usage in pipeline is as simple as:
log 'some message'
I have a global shared library on Jenkins implicitly loaded on all pipelines, then my Jenkinsfile is like that:
new com.company.Pipeline()()
And then the shared library has on directory src/com/company some files, below the Pipeline.groovy class:
package com.company
import static Utils.*
def call() {
// some stuff here...
}
The problem is, this way I have to static declare all methods, thus I lose the context and cannot access jenkins' methods easly without the Pipeline class' instance. As you can see here they passing this to the method mvn.
Thinking of avoid this I was wondering about dynamically add all methods as closures by calling Utils.install this instead of using import static Utils.*, then my Utils.groovy is something like that:
package com.company
private Utils() {}
static def install(def instance) {
def utils = new Utils()
// Some extra check needed here I know, but it is not the problem now
for (def method in (utils.metaClass.methods*.name as Set) - (instance.metaClass.methods*.name as Set)) {
def closure = utils.&"$method"
closure.delegate = instance
instance.metaClass."$method" = closure
}
}
def someMethod() {
// here I want to use sh(), tool(), and other stuff freely.
}
But it raises an GStringImpl cannot be cast to String error, I believe .& do not work with variables, how can I convert a method into closure having the method name on a variable? I have the MetaMethod mostly being a CachedMethod instance, if it were possible to turn it a ClosureMetaMethod instance maybe the problem can be solved, but whenever I search for method to closure conversion for groovy I just found the .& solution!
If I use instance.metaClass.someMethod = utils.&someMethod it do work, but I want it to be dinamic as I add new methods without needing to worry about sharing it.
There is a way to do it dynamically. Notation utils.&someMethod returns a MethodClosure object that can be simply instantiated with its constructor:
MethodClosure(Object owner, String method)
Consider following example:
class Utils {
def foo() {
println "Hello, Foo!"
}
def bar() {
println "Hello, Bar!"
}
}
class Consumer {
}
def instance = new Consumer()
def utils = new Utils()
(utils.metaClass.methods*.name - instance.metaClass.methods*.name).each { method ->
def closure = new MethodClosure(utils, method)
closure.delegate = instance
instance.metaClass."$method" = closure
}
instance.foo() // Prints "Hello, Foo!"
instance.bar() // Prints "Hello, Bar!"
In this example I use def closure = new MethodClosure(utils, method) to get object method reference and then add this method to instance object. I hope it helps.
I would like to implement an observer pattern in Dart but I'm not sure how to go about it.
Let's say I have a class:
class MyClass {
String observed_field;
}
Now, whenever I change the field, I'd like to print "observed_field changed" string into the console. Pretty simple to do with a custom setter:
class MyClass {
String _observed_field;
get observed_field => _observed_field;
set observed_field(v) {
_observed_field = v;
print("observed_field changed");
}
}
Now, of course, if I have not one, but many of those fields, I wouldn't want to create all those getters and setters. The obvious theoretical solution is to have them dynamically added to the class with something like this (not a working code, just an example of how I wish it looked):
class MyClass
String _observeable_field;
String _observeable_field_2;
observe(#observeable_field, #observeable_field_2);
end
Is it even possible? Additionally, it would be super awesome to not have those fields defined above the observe() call, but rather write something like:
observe(String: #_observeable_field, String: #_observeable_field_2);
So that those fields are declared automatically.
Here's a way to do it using the Observe package. The example is taken from code comments in that package (and adapted to your example above). Essentially, you annotate fields you want to be observable with the #observable annotation, and then listen for changes (which you trigger with the call to Observable.dirtyCheck();
First, add the observable package in your pubspec.yaml
dependencies:
observe: any
Then create a quick test program...
import 'package:observe/observe.dart';
class MyClass extends Object with Observable {
#observable String observedField = "Hello";
toString() => observedField.toString();
}
main() {
var obj = new MyClass();
// anonymous function that executes when there are changes
obj.changes.listen((records) {
print('Changes to $obj were: $records');
});
obj.observedField = "Hello World";
// No changes are delivered until we check for them
Observable.dirtyCheck();
print('done!');
}
This produces the following output:
Changes to Hello World were: [#<PropertyChangeRecord Symbol("observedField") from: Hello to: Hello World>]
done!
Update in response to comments...
Updating the example to omit the Observable.dirtyCheck() you can use a setter and notifyPropertyChanged, with the class instead mixing in ChangeNotifier
class MyClass2 extends Object with ChangeNotifier {
String _observedField = "Hello";
#reflectable get observedField => _observedField;
#reflectable set observedField(v) {
_observedField = notifyPropertyChange(#observedField, _observedField, v);
}
toString() => observedField;
}
This is a base trait that I use in my tiny parser app:
trait Token[ValueType] {
def value: ValueType
}
This is what I require. I'd also like to combine a good feature of Java with a good feature of Scala i.e.:
Java approach to enums (they're normal objects with methods, can ihnerit etc.)
Scala suport for matching (readable code)
so an example of classes extending Token are:
// this to emulate Java enums; ProperEnumeration just adds some simple methods like fromChars etc.
object Keywords extends ProperEnumeration {
val AND, ARRAY, BEGIN, CASE, CONST, ... = Value
}
// this to enable matching
final case class Keyword(keyword: Keywords.Value) extends Token[Keywords.Value] {
def this(string: String) = this(Keywords.fromString(string))
def value = keyword
}
object SpecialSymbols extends ProperEnumeration {
val LEFT_BRACE = Value("{")
val RIGHT_BRACE = Value("}")
...
}
final case class SpecialSymbol(symbol: SpecialSymbols.Value) extends Token[SpecialSymbols.Value] {
def this(symbol: String) = this(SpecialSymbols.fromString(symbol))
def value = symbol
}
// there are also non-enum subclasses of Token
case class Identifier(identifier: String) extends Token[String] {
override def value: String = identifier
}
This is the best I came up with. I can use it like this:
token match {
case Keyword(Keywords.BEGIN) => ...
case SpecialSymbol(SpecialSymbols.LEFT_BRACE) => ...
case Identifier(name) => ...
}
I'd like to modify it to allow me to be more concise, I'd like something like this:
token match {
case Keyword.BEGIN => ... // or Keyword(BEGIN)
case SpecialSymbol.LEFT_BRACE => ...
case Identifier(name) => ...
}
to also suport a method called consume that would work with any kind of Token subclass (consume should throw an exception if the next token from source is NOT the argument supplied).
consume(Keyword.BEGIN);
consume(SpecialSymbol.LEFT_BRACE);
consume(Identifier(name));
I want the code to be clean, that's why I use Scala in the first place. So I hope for no function overloads to allow easy addition of Trait subclasses.
So, dear Scalists, what to do?
The simplest way to have
case Keyword(BEGIN) => ...
is to simply import the keywords:
import Keywords._
It won't require any other changes to your code.
However, I personally would prefer to avoid ProperEnumerarion and have a simple hierarchy of traits and case objects:
trait Keyword
case object BEGIN extends Keyword
case object CASE extends Keyword
This will automatically give pattern matching:
token match {
case BEGIN => ...
}
If you need some methods in objects you may have them declared in the trait of have some abstract class (with a constructor):
abstract class Keyword(val name:String) {
def myMethod = "Keyword."+name
}
case object BEGIN extends Keyword("BEGIN")
case object CASE extends Keyword("CASE")
UPD: You may use an object that instantiates "enum" instances the same way as Enumeration:
object AllMyKeywords {
val BEGIN = Keyword("BEGIN")
val CASE = Keyword("CASE")
// etc.
val values = List(BEGIN, CASE, ...).map(k => (k.name, k)).toMap
}
UPD2: There is also a way to make pattern matching with strings:
abstract class Keyword(val name:String) {
def unapply(str:String):Option[Keyword] = {
if(AllMyKeywords.values.contains(str))
Some(AllMyKeywords.values(str)
else
None
}
}
In this case the unapply method is implemented by every BEGIN, CASE keywords and thus it is directly called (at least I think so).
"BEGIN" match { case BEGIN => ??? }
I want to override a method definition in Grails. I am trying to use Groovy metaprogramming as the class which I want to override belongs to a framework.
Below is the original class.
class SpringSocialSimpleSignInAdapter implements SignInAdapter {
private RequestCache requestCache
SpringSocialSimpleSignInAdapter(RequestCache requestCache) {
this.requestCache = requestCache;
}
String signIn(String localUserId, Connection<?> connection, NativeWebRequest request) {
SignInUtils.signin localUserId
extractOriginalUrl request
}
}
I am trying to override like below
SpringSocialSimpleSignInAdapter.metaClass.signIn = {java.lang.String str, org.springframework.social.connect.Connection conn, org.springframework.web.context.request.NativeWebRequest webreq ->
println 'coming here....' // my implementation here
return 'something'
}
But for some reason overriding is not hapening. I am not able to figure it out. Any help would be greatly appretiated.
Thanks
Yeah, seems like that bug. I don't know your whole scenario, but anyway, here's a small workaround i made:
In your class definition, you don't implement the interface
You create your object and do your metamagic
Use groovy coercion to make it act as the interface and then you can pass it around
Here is a small script i made using JIRA bug to prove it:
interface I {
def doIt()
}
class T /*implements I*/ {
def doIt() { true }
}
def t = new T()
assert t.doIt()
t.metaClass.doIt = { -> false }
// here the coercion happens and the assertion works fine
def i = t as I
assert !i.doIt()
assert !t.doIt()
// here the polymorphism happens fine
def iOnlyAcceptInterface(I i) { assert !i.doIt() }
iOnlyAcceptInterface(i)