I have a jQuery UI element and I want to write something like that
$('myAccordion').accordion("refresh")
However, this does not compile since I only have a facade for jQuery - not jQuery UI.
How can I proceed here?
Basically, you write a mini-facade for the function you need. This looks intimidating, but the key is that you only need to write what you actually use, so it's pretty simple.
Mind, this is off-the-cuff and not tested, but a simplistic version would be something like this:
#js.native
trait JQueryAccordionFacade extends js.Object {
def accordion(cmd:String):JQuery = js.native
}
...
implicit def jq2Accordion(jq:JQuery):JQueryAccordionFacade = jq.asInstanceOf[JQueryAccordionFacade]
You'll need some imports and stuff, and obviously this could be written in a more strongly-typed fashion, but that's most of it: just a description of the function you want to call, and the implicit conversion from an ordinary JQuery facade to the Accordion one. Facade-writing's pretty easy, once you get the hang of it.
Here are a couple of examples of some fully-worked jQuery UI facades, and here are the full details on how to write jQuery facades (far more than you need here, but in case you want to push this further).
Related
I am not sure the keywords for this pattern, sorry if the question is not clear.
If you have:
case class MyFancyWrapper(
somethingElse: Any,
heavyComplexObject: CrazyThing
)
val w = MyFancyWrapper(???, complexThing)
I want to be able to call w.method with the method coming from complexThing. I tried to extends CrazyThing but it is a trait and I don't want to implement all the method that would be very tedious. I also don't want to have to do:
def method1 = heavyComplexObject.method1
...
for all of them.
Any solution ?
Thanks.
You can do this with macros but I agree with Luis that this is an overkill. Macros are intended to repetitive boring things, not one time boring things. Also this is not as trivial as it sounds, because you probably don't want to pass through all the methods (you probably still want your own hashCode and equals). Finally macros have bad IDE support so most probably no auto-completion for all those methods. On the other hand if you do use a good IDE (like IDEA) there is most probably an action like "Delegate methods" that will generate most of the code for you. You still will have to change the return type from Unit to MyFancyWrapper and add returning this at the end of each method but this can easily be done with mass replace operations (hint: replace "}" with "this }" and the automatically re-formatting code should do the trick)
Here are some screenshots of the process from JetBrains IDEA:
You can use an implicit conversion to make all the methods of heavyComplexThing directly available on MyFancyWrapper:
implicit def toHeavy(fancy: MyFancyWrapper): CrazyThing = fancy.heavyComplexObject
This needs to be in scope when the method is called.
In the comments you indicate that you want to return this so that you can chain multiple calls on the same object:
w.method1.method2.method3
Don't do this
While this is a common pattern in non-functional languages, it is bad practice is Scala for two reasons:
This pattern inherently relies on side-effects, which is the antithesis of functional programming.
It is confusing, because in Scala chaining calls in this way is used to implement a data pipeline, where the output of one function is passed as the input to the next.
It is much clearer to write separate statements so that it is obvious that the methods are being called on the same object:
w.method1()
w.method2()
w.method3()
(It is also conventional to use () when calling methods with side effects)
Scala SIP 18 provides a way to force users to provide an import statement to use certain advanced or unsafe language features. For instance, in order to use higher kinded types, you need to
import scala.language.higherKinds
or you will get a compiler warning telling you you are using an advanced feature.
Is there any way that I can reproduce or mimic this behavior in my own library? For example I may have:
trait MongoRepository[E <: Entity] {
val casbahCollection: com.mongodb.casbah.MongoCollection
}
I have made the casbahCollection public to expose the underlying collection to the user in case they need it. But it's really not something I want my users to do because it's a leaky abstraction. So I want to force them to do something like this:
import my.library.mongo.leakyAbstraction
Before doing something like this:
widgetRepo.casbahCollection.find()
Is it possible? Is there some way I might provide a similar behavior that's a little more effective than just placing a big ugly warning in the docs?
You could fake it with an implicit, similar to the way Await.result works in scala.concurrent.
First create a sealed trait that represents a "permit" to directly access your DAO:
#implicitNotFound("Import my.library.mongo.leakyAbstraction to directly access Mongo")
sealed trait CanAccessMongo
And then an object that extends it:
implicit object leakyAbstraction extends CanAccessMongo
These must be in the same file. By making CanAccessMongo sealed, code outside the same file will not be able to extend it.
Then in MongoRepository make cashbahCollection a function (change val to def). You'll probably want a private val that actually creates it, but we need the function to limit access.
def cashbahCollection(implicit permit: CanAccessMongo) = ...
Now users of your library will have to bring leakyAbstraction into scope in order to call that function. If they don't, they'll get the error message specified in implicitNotFound.
The obvious downside is that all your library code will have to have leakyAbstraction in scope as well.
We are pretty familiar with implicits in Scala for now, but macros are pretty undiscovered area (at least for me) and, despite the presence of some great articles by Eugene Burmako, it is still not an easy material to just dive in.
In this particular question I'd like to find out if there is a possibility to achieve the analogous to the following code functionality using just macros:
implicit class Nonsense(val s: String) {
def ##(i:Int) = s.charAt(i)
}
So "asd" ## 0 will return 'a', for example. Can I implement macros that use infix notation? The reason to this is I'm writing a DSL for some already existing project and implicits allow making the API clear and concise, but whenever I write a new implicit class, I feel like introducing a new speed-reducing factor. And yes, I do know about value classes and stuff, I just think it would be really great if my DSL transformed into the underlying library API calls during compilation rather than in runtime.
TL;DR: can I replace implicits with macros while not changing the API? Can I write macros in infix form? Is there something even more suitable for this case? Is the trouble worth it?
UPD. To those advocating the value classes: in my case I have a little more than just a simple wrapper - they are often stacked. For example, I have an implicit class that takes some parameters, returns a lambda wrapping this parameters (i.e. partial function), and the second implicit class that is made specifically for wrapping this type of functions. I can achieve something like this:
a --> x ==> b
where first class wraps a and adds --> method, and the second one wraps the return type of a --> x and defines ==>(b). Plus it may really be the case when user creates considerable amount of objects in this fashion. I just don't know if this will be efficient, so if you could tell me that value classes cover this case - I'd be really glad to know that.
Back in the day (2.10.0-RC1) I had trouble using implicit classes for macros (sorry, I don't recollect why exactly) but the solution was to use:
an implicit def macro to convert to a class
define the infix operator as a def macro in that class
So something like the following might work for you:
implicit def toNonsense(s:String): Nonsense = macro ...
...
class Nonsense(...){
...
def ##(...):... = macro ...
...
}
That was pretty painful to implement. That being said, macro have become easier to implement since.
If you want to check what I did, because I'm not sure that applies to what you want to do, refer to this excerpt of my code (non-idiomatic style).
I won't address the relevance of that here, as it's been commented by others.
I found this code example in Programming in Scala, 2nd Ed. (Chapter 25, Listing 25.11):
object PrefixMap extends {
def empty[T] = ...
def apply[T](kvs: (String, T)*): PrefixMap[T] = ...
...
}
Why is the extends clause there without a superclass name? It looks like extending an anonymous class, but for what purpose? The accompanying text doesn't explain or even mention this construct anywhere. The code actually compiles and apparently works perfectly with or without it.
OTOH I found the exact same code on several web pages, including this (which looks like the original version of the chapter in the book). I doubt that a typo could have passed below the radars of so many readers up to now... so am I missing something?
I tried to google it, but struggled even to find proper search terms for it. So could someone explain whether this construct has a name and/or practical use in Scala?
Looks like a print error to me. It will work all the same, though, which probably helped hide it all this time.
Anyway, that object is extending a structural type, though it could also be an early initialization, if you had with XXX at the end. MMmmm. It looks more like an early initialization without any class or trait to be initialized later, actually... structure types do not contain code, I think.
Let's say I have the following class:
class Person(val firstName:String, val lastName:String)
Is there an automatic way to generate xml from this class without having to hand create a toXml() method? Ideally the output would be something like:
<Person>
<firstName>John</firstName>
<lastName>Smith</lastName>
</Person>
It seems like there should be a way to do this without having to write all that out manually. Perhaps there is a trait I haven't found yet?
For case classes (or other subclasses of Product), this was once very easy to write generically: the name can be retrieved with productPrefix, all values are iterable via productIterator and the names of the fields via productElementName.
Unfortunately, productElementName has only had a very short life: it was added in revision 20958 and removed in revision 21223, apparently because it added too much weight to case classes (there's also an open ticket for it).
Unfortunately, I don't think there is such a magic trait. You could use something like XStream to accomplish this. However, it doesn't seem print all Scala classes that pretty automatically, so you probably need to write your own converter. Someone else has already done so in the case of Lists, I guess for your example you might need something similar.