CoffeeScript dynamic methods - metaprogramming

I'm trying to create methods dynamically in coffee script, but as my code shows, the iterator I use to create the methods doesn't reset its variables between iterations and so I en up with shared variables that conflicts:
class MyClass
constructor: (#name) ->
for k, v of ['get', 'set']
console.log('creating method: ' + v)
MyClass::[v] = (args...) ->
method = v
console.log('executing method: ' + method)
o = new MyClass('dummy')
o.get()
o.set()
Outputs:
> creating method: get
> creating method: set
> executing method: set
> executing method: set
one knows what I'm doing wrong?

mu has correctly diagnosed the problem. The most direct solution is to use the CoffeeScript language's do keyword, which creates and runs an inner function that captures the values of the variables you pass in:
for k, v of ['get', 'set']
do (k, v) ->
console.log('creating method: ' + v)
MyClass::[v] = (args...) ->
method = v
console.log('executing method: ' + method)
I talk about this feature in my PragPub article, A CoffeeScript Intervention.

Your inner function:
(args...) ->
method = v
console.log('executing method: ' + method)
is actually a closure on v so when it is executed, v will evaluate to its last value in the loop (i.e. set). Looks like you just need a bit of closure busting:
build_method = (v) ->
(args...) ->
method = v
console.log('executing method: ' + method)
And then:
for k, v of ['get', 'set']
console.log('creating method: ' + v)
MyClass::[v] = build_method(v)
Keep in mind that CoffeeScript is just JavaScript with different makeup so it suffers from a lot of the same problems (as does any language with closures) and those problems have the same solutions.

Related

Is it possible to provide a setter function in my computational expression?

I'm trying to write an F# computational expression that permits reading and writing thread-safe variables only from within a critical section.
I've got a type, ThreadSafeVar<'t> that wraps a value, a CriticalSection<'t> and a computational expression builder, LockContext, as follows:
// wraps a value and restricts access to it
type ThreadSafeVar<'t> (value: 't) =
member val internal Value = value with get, set
// Encapsulates a critical section
type CriticalSection<'t> =
private
{ LockObj: obj
fn: unit -> 't }
static member Lock(lc: CriticalSection<'t>) = lock lc.LockObj lc.fn
// Expression builder for a locked context
type LockContext () =
member internal this.SyncRoot = obj()
member this.Return(value: 'v) = value
member this.ReturnFrom(value: ThreadSafeVar<'t>) = value.Value
member __.Bind(value: ThreadSafeVar<'t>, fn: 't -> 'u) = fn value.Value
// returns a CriticalSection
member this.Run(fn : unit -> 'u) = { LockObj = this.SyncRoot
fn=fn }
.
.
.
Reading the thread-safe values from within a lock context is simple enough thanks to Bind. e.g.
let lockedInt = ThreadSafeVar(1) // create a thread-safe variable
let context = LockContext()
let wrapperVal = context {
let! i = lockedInt // get the wrapper value inside lockedInt
return i
} |> CriticalSection.Lock
But I'm struggling to understand how to implement a means setting the value from within a LockContext instance. The approach I've thus taken is to implement a custom operation called, for instance, setVal. I've included my attempts thus far but I'm afraid they'd just muddy the waters. It seems that custom operations operate upon the computation built so far within the expression, encoded as a tuple, but I don't see that this is required in my case.
Any hints, pointing to resources, or direct help would be appreciated.
I'm not at all sure of the wisdom of this, but I came up with something based on the State monad that might work for you. First, define a "stateful" function as one that takes a ThreadSafeVar and returns some type of result:
ThreadSafeVar<'state> -> 'result
We then put that signature into a type that represents a stateful computation:
type Stateful<'state, 'result> =
MkStateful of (ThreadSafeVar<'state> -> 'result)
Now we need a way to run such a computation safely using a given TSV:
let run (tsv : ThreadSafeVar<_>) (MkStateful f) =
lock tsv (fun () -> f tsv)
Note that I've gotten rid of your CriticalSection type and instead just lock the TSV itself.
Next, we need a way to lift a pure value into a stateful computation:
let lift value =
MkStateful (fun _ -> value)
And a way to bind two stateful computations together:
let bind binder stateful =
MkStateful (fun tsv ->
run tsv stateful
|> binder
|> run tsv)
Defining the builder is then trivial:
type LockContext () =
member __.Return(value) = lift value
member __.Bind(stateful, binder) = bind binder stateful
let context = LockContext()
We also need helper computations for setting and getting a value safely:
let getValue =
MkStateful (fun tsv ->
tsv.Value)
let setValue value =
MkStateful (fun tsv ->
tsv.Value <- value)
Putting it all together, we can define a computation that increments the value of a TSV:
let comp =
context {
let! oldValue = getValue
let newValue = oldValue + 1
do! setValue newValue
return newValue
}
And we can run it like this:
let lockedInt = ThreadSafeVar(1)
let result = comp |> run lockedInt
printfn "%A" result // output is: 2
You can see the full solution and try it yourself here.

Groovy metaclass add multiple methods based on invocation order not mock

I am trying to overwrite method Call on the groovy sql class and i am able to do it.But i need to have different implementations based on order.
Sql.metaClass.call = {String sql, List params, Closure c -> c(mockResultSet)} //first time should call this method
Sql.metaClass.call = {String sql, List params, Closure c -> c(expectedLookupId)} //second time should call this method.
One way to implement it would be using an internal flag in the class.
Then call the different implementations based on the flag.
Sql.metaClass.first = true
Sql.metaClass.call = {String sql, List params, Closure c ->
if (first){
c(mockResultSet)
first = false
}else{
c(expectedLookupId)
}
}
Thanks #Joachim for the suggestion.This worked for me.
def counter = 1
Sql.metaClass.call = {String sql, List params, Closure c ->
if(counter ==1 ) {
c(mockResultSet)
counter++;
}else{
c(expectedLookupId)
}
}

Synchronizing on function parameter for multithreaded memoization

My core question is: how can I implement synchronization in a method on the combination of the object instance and the method parameter?
Here are the details of my situation. I'm using the following code to implement memoization, adapted from this answer:
/**
* Memoizes a unary function
* #param f the function to memoize
* #tparam T the argument type
* #tparam R the result type
*/
class Memoized[-T, +R](f: T => R) extends (T => R) {
import scala.collection.mutable
private[this] val cache = mutable.Map.empty[T, R]
def apply(x: T): R = cache.getOrElse(x, {
val y = f(x)
cache += ((x, y))
y
})
}
In my project, I'm memoizing Futures to deduplicate asynchronous API calls. This worked fine when using for...yield to map over the resulting futures, created with the standard ExcecutionContext, but when I upgraded to Scala Async for nicer handling of these futures. However, I realized that the multithreading that library uses allowed multiple threads to enter apply, defeating memoization, because the async blocks all executed in parallel, entering the "orElse" thunk before cache could be updated with a new Future.
To work around this, I put the main apply function in a this.synchronized block:
def apply(x: T): R = this.synchronized {
cache.getOrElse(x, {
val y = f(x)
cache += ((x, y))
y
})
}
This restored the memoized behavior. The drawback is that this will block calls with different params, at least until the Future is created. I'm wondering if there is a way to set up finer grained synchronization on the combination of the Memoized instance and the value of the x parameter to apply. That way, only calls that would be deduplicated will be blocked.
As a side note, I'm not sure this is truly performance critical, because the synchronized block will release once the Future is created and returned (I think?). But if there are any concerns with this that I'm not thinking of, I would also like to know.
Akka actors combined with futures provide a powerful way to wrap over mutable state without blocking. Here is a simple example of how to use an Actor for memoization:
import akka.actor._
import akka.util.Timeout
import akka.pattern.ask
import scala.concurrent._
import scala.concurrent.duration._
class Memoize(system: ActorSystem) {
class CacheActor(f: Any => Future[Any]) extends Actor {
private[this] val cache = scala.collection.mutable.Map.empty[Any, Future[Any]]
def receive = {
case x => sender ! cache.getOrElseUpdate(x, f(x))
}
}
def apply[K, V](f: K => Future[V]): K => Future[V] = {
val fCast = f.asInstanceOf[Any => Future[Any]]
val actorRef = system.actorOf(Props(new CacheActor(fCast)))
implicit val timeout = Timeout(5.seconds)
import system.dispatcher
x => actorRef.ask(x).asInstanceOf[Future[Future[V]]].flatMap(identity)
}
}
We can use it like:
val system = ActorSystem()
val memoize = new Memoize(system)
val f = memoize { x: Int =>
println("Computing for " + x)
scala.concurrent.Future.successful {
Thread.sleep(1000)
x + 1
}
}
import system.dispatcher
f(5).foreach(println)
f(5).foreach(println)
And "Computing for 5" will only print a single time, but "6" will print twice.
There are some scary looking asInstanceOf calls, but it is perfectly type-safe.

Mapping sub-sets of parentheses to chars

I am attempting to create a Scala method that will take one parent group of parentheses, represented as a String, and then map each subgroup of parentheses to a different letter. It should then put these in a map which it returns, so basically I call the following method like this:
val s = "((2((x+3)+6)))"
val map = mapParentheses(s)
Where s could contain any number of sets of parentheses, and the Map returned should contain:
"(x+3)" -> 'a'
"(a+6)" -> 'b'
"(2b)" -> 'c'
"(c)" -> 'd'
So that elsewhere in my program I can recall 'd' and get "(c)" which will become "((2b))" then ((2(a+6))) and finally ((2((x+3)+6))). The string sent to the method mapParentheses will never have unmatched parentheses, or extra chars outside of the main parent parentheses, so the following items will never be sent:
"(fsf)a" because the a is outside the parent parentheses
"(a(aa))(a)" because the (a) is outside the parent parentheses
"((a)" because the parentheses are unmatched
")a(" because the parentheses are unmatched
So I was wondering if anyone knew of an easy (or not easy) way of creating this mapParentheses method.
You can do this pretty easily with Scala's parser combinators. First for the import and some simple data structures:
import scala.collection.mutable.Queue
import scala.util.parsing.combinator._
sealed trait Block {
def text: String
}
case class Stuff(text: String) extends Block
case class Paren(m: List[(String, Char)]) extends Block {
val text = m.head._2.toString
def toMap = m.map { case (k, v) => "(" + k + ")" -> v }.toMap
}
I.e., a block represents a substring of the input that is either some non-parenthetical stuff or a parenthetical.
Now for the parser itself:
class ParenParser(fresh: Queue[Char]) extends RegexParsers {
val stuff: Parser[Stuff] = "[^\\(\\)]+".r ^^ (Stuff(_))
def paren: Parser[Paren] = ("(" ~> insides <~ ")") ^^ {
case (s, m) => Paren((s -> fresh.dequeue) :: m)
}
def insides: Parser[(String, List[(String, Char)])] =
rep1(paren | stuff) ^^ { blocks =>
val s = blocks.flatMap(_.text)(collection.breakOut)
val m = blocks.collect {
case Paren(n) => n
}.foldLeft(List.empty[(String, Char)])(_ ++ _)
(s, m)
}
def parse(input: String) = this.parseAll(paren, input).get.toMap
}
Using get in the last line is very much not ideal, but is justified by your assertion that we can expect well-formed input.
Now we can create a new parser and pass in a mutable queue with some fresh variables:
val parser = new ParenParser(Queue('a', 'b', 'c', 'd', 'e', 'f'))
And now try out your test string:
scala> println(parser parse "((2((x+3)+6)))")
Map((c) -> d, (2b) -> c, (a+6) -> b, (x+3) -> a)
As desired. A more interesting exercise (left to the reader) would be to thread some state through the parser to avoid the mutable queue.
Classic recursive parsing problem. It can be handy to hold the different bits. We'll add a few utility methods to help us out later.
trait Part {
def text: String
override def toString = text
}
class Text(val text: String) extends Part {}
class Parens(val contents: Seq[Part]) extends Part {
val text = "(" + contents.mkString + ")"
def mapText(m: Map[Parens, Char]) = {
val inside = contents.collect{
case p: Parens => m(p).toString
case x => x.toString
}
"(" + inside.mkString + ")"
}
override def equals(a: Any) = a match {
case p: Parens => text == p.text
case _ => false
}
override def hashCode = text.hashCode
}
Now you need to parse into these things:
def str2parens(s: String): (Parens, String) = {
def fail = throw new Exception("Wait, you told me the input would be perfect.")
if (s(0) != '(') fail
def parts(s: String, found: Seq[Part] = Vector.empty): (Seq[Part], String) = {
if (s(0)==')') (found,s)
else if (s(0)=='(') {
val (p,s2) = str2parens(s)
parts(s2, found :+ p)
}
else {
val (tx,s2) = s.span(c => c != '(' && c != ')')
parts(s2, found :+ new Text(tx))
}
}
val (inside, more) = parts(s.tail)
if (more(0)!=')') fail
(new Parens(inside), more.tail)
}
Now we've got the whole thing parsed. So let's find all the bits.
def findParens(p: Parens): Set[Parens] = {
val inside = p.contents.collect{ case q: Parens => findParens(q) }
inside.foldLeft(Set(p)){_ | _}
}
Now we can build the map you want.
def mapParentheses(s: String) = {
val (p,_) = str2parens(s)
val pmap = findParens(p).toSeq.sortBy(_.text.length).zipWithIndex.toMap
val p2c = pmap.mapValues(i => ('a'+i).toChar)
p2c.map{ case(p,c) => (p.mapText(p2c), c) }.toMap
}
Evidence that it works:
scala> val s = "((2((x+3)+6)))"
s: java.lang.String = ((2((x+3)+6)))
scala> val map = mapParentheses(s)
map: scala.collection.immutable.Map[java.lang.String,Char] =
Map((x+3) -> a, (a+6) -> b, (2b) -> c, (c) -> d)
I will leave it as an exercise to the reader to figure out how it works, with the hint that recursion is a really powerful way to parse recursive structures.
def parse(s: String,
c: Char = 'a', out: Map[Char, String] = Map() ): Option[Map[Char, String]] =
"""\([^\(\)]*\)""".r.findFirstIn(s) match {
case Some(m) => parse(s.replace(m, c.toString), (c + 1).toChar , out + (c -> m))
case None if s.length == 1 => Some(out)
case _ => None
}
This outputs an Option containing a Map if it parses, which is better than throwing an exception if it doesn't. I suspect you really wanted a map from Char to the String, so that's what this outputs. c and out are default parameters so you don't need to input them yourself. The regex just means "any number of characters that aren't parens, eclosed in parens" (the paren characters need to be escaped with "\"). findFirstIn finds the first match and returns an Option[String], which we can pattern match on, replacing that string with the relevant character.
val s = "((2((x+3)+6)))"
parse(s) //Some(Map(a -> (x+3), b -> (a+6), c -> (2b), d -> (c)))
parse("(a(aa))(a)") //None

Dotted strings to properties

I've got a hash of strings similar to this:
Map map = ['a.b.c': 'Hi']
... that I need to use in gradle to expand an expression like this:
This is a greeting: ${a.b.c}
If I use the gradle copy task with expand I will get an error message 'No such property: a'.
Is there any way to get gradle/groovy to convert that map into the properties I need to resolve?
I couldn't find a built-in answer, but it here is a complete, self-contained method that can be used as a meta method on Map to do what you want:
Map map = ['a.b.c': 'Hi', 'a.b.d': 'Yo', 'f.g.h': 'Howdy']
Map.metaClass.expandKeys = { separator = '.' ->
def mergeMaps = { a, b ->
b.each{ k, v ->
if(a[k] && (v instanceof Map)) {
mergeMaps(a[k], v)
} else {
a[k] = v
}
}
a
}
delegate.inject([:]){ result, k, v ->
mergeMaps(result, k.tokenize(separator).reverse().inject(v){last, subkey -> [(subkey):last] })
}
}
assert map.expandKeys() == [a:[b:[c:"Hi", d:"Yo"]], f:[g:[h:"Howdy"]]]
It also allows for different separators than ., just pass the separator into the expandKeys method
If you want to use it like a normal function, then you can do this instead:
Map map = ['a.b.c': 'Hi', 'a.b.d': 'Yo', 'f.g.h': 'Howdy']
def expandKeys = { Map input, separator = '.' ->
def mergeMaps = { a, b ->
b.each{ k, v ->
if(a[k] && (v instanceof Map)) {
mergeMaps(a[k], v)
} else {
a[k] = v
}
}
a
}
input.inject([:]){ result, k, v ->
mergeMaps(result, k.tokenize(separator).reverse().inject(v){last, subkey -> [(subkey):last] })
}
}
assert expandKeys(map) == [a:[b:[c:"Hi", d:"Yo"]], f:[g:[h:"Howdy"]]]
The main trick, besides merging the maps, is to split then reverse each key. Then the final hierarchy can be built up backwards. Also, there may be a better way to handle the merge, because I don't like the hanging a at the end.
I don't know anything about Gradle but maybe this will help....
If you have a Map
Map map = ['a.b.c': 'Hi']
Then you can't retrieve the value 'Hi' using
map.a.b.c
Instead, you must use:
map.'a.b.c'
or
map['a.b.c']
I'm not exactly sure what your needs are, but if you just need to replace property-like tokens and don't need the full power of Groovy templates, the filter() method in combination with Ant's ReplaceTokens class is a safer (and faster) bet than expand(). See Filtering files in the Gradle User Guide.

Resources