I'm writing Express.js modules in CoffeeScript, and I'm not sure of the best way to structure them.
The way I want to utilize the module is something like
app.coffee
Mailer = require('./lib/mailer')
amazon_mailer = new Mailer
key: "somekey"
secret: "somesecret"
type: "SES"
...
amazon_mailer.send(...)
So, in Coffeescript, I'm thinking about doing it this way:
/lib/mailer.coffee
class Mailer
constructor: (options) ->
#options = options
send: (...) ->
...
module.exports = Mailer
In my testing, this works, but is it the proper way to do it? I've been unable to find any good examples about how to structure express modules in CoffeeScript. Is there a better way to do it?
Yes, your approach is fine. It's common to export a constructor from a Node library.
The only thing you have to worry about is exporting the Mailer class in such a way that it can be required directly. You can do that by adding the line
module.exports = Mailer
after defining the class.
Related
I'm currently working with reasonably large code base where new code is written in scala, but where a lot of old Java code remains. In particular there are a lot of java APIs we have to talk to. The old code uses simple Java Pojos with public non-final fields, without any methods or constructors, e.g:
public class MyJavaPojo {
public String myField1;
public MyOtheJavaPojo myField2;
}
Note that we dont have the option of adding helper methods or constructors to these types. These are currently created like old c-structs (pre-named parameters) like this:
val myPojo = new MyJavaPojo
myPojo.myField1 = ...
myPojo.myField2 = ...
Because of this, it's very easy to forget about assigning one of the fields, especially when we suddenly add new fields to the MyJavaPojo class, the compiler wont complain that I've left one field to null.
NOTE: We don't have the option of modifying the java types/adding constructors the normal way. We also don't want to start creating lots and lots of manually created helper functions for object creation - We would really like to find a solution based on scala macros instead of possible!
What I would like to do would be to create a macro that generates either a constructor-like method for my Pojos or a macro that creates a factory, allowing for named parameters. (Basically letting a macro do the work instead of creating a gazillion manually written helper methods in scala).
Do you know of any way to do this with scala macros? (I'm certain it's possible, but I've never written a scala macro in my life)
Desired API alternative 1:
val myPojo = someMacro[MyJavaPojo](myField1 = ..., myField2 = ...)
Desired API alternative 2
val factory = someMacro[MyJavaPojo]
val myPojo = factory.apply(myField1 = ..., myField2 = ...)
NOTE/Important: Named parameters!
I'm looking for either a ready-to-use solution or hints as to where I can read up on making one.
All ideas and input appreciated!
Take a look at scala-beanutils.
#beanCompanion[MyJavaPojo] object MyScalaPojo
MyScalaPojo(...)
It probably won't work directly, as you classes are not beans and it's only been made for Scala 2.10, but the source code is < 200 lines and should give you an idea of where to start.
I have been looking for a while for a tern.js plugin that would allow me to use simple inline type annotations like this:
var f = function(/* string */ a) { ... }
This is a simple style that, for instance, Brackets supports.
I am aware that I can use JSDoc plugin with tern.js, but that requires a little more verbose syntax, that is especially difficult to use in anonymous functions.
Can I make JSDoc plugin parse these simple annotations or is there another plugin for that?
I've created some utilities that help me at generating HTML and I reference them in my views as #div( "class" -> "well" ){ Hello Well. }. Until now those classes were subclassing NodeSeq because they aren't escaped then. But I need to get rid off the NodeSeq in the top of my class hierarchy because Scala's xml is flawed and makes my code hacky and because I could switch to Traits then.
So I tried to find out how to prevent Play from escaping my Tag-objects. But unfortunately the only valid solution that I found is to override the template compiler and have the user specify my compiler in his Build.scala settings.
But I hopefully have overlooked a way more simple approach?
If your html helpers returns 'Html' rather than String you don't need to wrap them using the #Html tag in the view.
eg
import play.api.templates.Html
def a(src: String, value: String) : Html = Html(s"<a href='$src'>$value</a>")
Would be called in the view as below without needing to wrap in #Html
#a("www.example.com", "Example")
Since version 2.2.0-M1 there appeared a new approach in the docs that explains how to add custom formats to the template engine. This allows me to easily integrate my utilities.
Custom Template Format: Java, Scala
I'm switching from using DBIx::Class::Schema::Loader in dynamic mode to static.
But there's a problem, my result classes are mixed up with non result classes. Here's the specifics.
lib/BackPAN/Index.pm # main API
lib/BackPAN/Index/Dist.pm # result class
lib/BackPAN/Index/File.pm # result class
lib/BackPAN/Index/Release.pm # result class
lib/BackPAN/Index/Schema.pm # subclass of DBIC::Schema::Loader
lib/BackPAN/Index/Role/... # various roles
When I switch to static schema generation it gets tripped up by the role.
DBIx::Class::Schema::load_namespaces(): Attempt to load_namespaces()
class BackPAN::Index::Role::HasCache failed - are you sure this is a
real Result Class?
I'm stuck with this class layout. BackPAN::Index::Dist, File and Release are all publicly documented. Many methods are expected to return them as the result of queries.
I need a way to use DBIx::Class::Schema::Loader in static mode while BackPAN::Index::Dist, File and Release are used as result classes.
I've been trying to make DBIx::Class::Schema::Loader spell out the generated result classes rather than relying on load_namespaces to search the subdirectory.
Ideally, I'd like the generated result classes to be in their own subdirectory with Dist, File and Release as subclasses for easier customization. However, queries against the schema must return the customized subclasses.
Normally you have a Result and a ResultSet namespace in which the corresponding classes reside:
BackPAN::Index::Schema::Result::Dist
BackPAN::Index::Schema::ResultSet::Dist
The DBIx::Class::Schema#load_namespaces docs show an example of setting them to non-default values.
You can also use DBIx::Class::Schema#load_classes and specify each class:
BackPAN::Index::Schema->load_classes({
BackPAN::Index => [qw( Dist File Release )],
});
Normally it's not a problem to move Result and ResultSet classes into different namespaces because they are always accessed through an instance of the Schema which loads them.
I suggest trying to move them and see if it really breaks something before going with load_classes.
I realized the important part of Schema::Loader is making the result classes. The schema is simple and I can make it by hand. Unfortunately there's no way to tell Schema::Loader not to generate the schema. I've hacked around it by telling it to make a dummy and just delete the file.
DBIx::Class::Schema::Loader::make_schema_at(
'BackPAN::Index::SchemaThrowaway',
{
result_namespace => '+BackPAN::Index',
use_namespaces => 1,
dump_directory => 'lib',
},
);
# Throw the generated schema away.
unlink "lib/BackPAN/Index/SchemaThrowaway.pm";
Then I write the schema class by hand.
package BackPAN::Index::Schema;
use strict;
use warnings;
use base 'DBIx::Class::Schema';
__PACKAGE__->load_classes({
"BackPAN::Index" => [qw(Dist File Release)],
});
Its a hack, but it works. Still looking for a better solution.
Server = require('mongodb').Server
That's my CoffeeScript now. Any way to drop those ()?
This looks like a job for destructuring assignment!
{Server} = require 'mongodb'
Server = (require 'mongodb').Server
There's really no way to demarcate these two expressions clearly using only whitespace. I tried:
Server = require 'mongodb'
.Server
But the resulting javascript was:
var server = require('Server'.Server);
Which is obviously wrong and not what you want.
The correct answer here is 'no.'
Parentheses are important; they allow you to isolate and demarcate expressions. For all of Coffeescript's amazing power to handle some obvious isolations by itself, not every expression can be parsed automagically. Embrace the parenthetical!
mongo = require 'mongodb'
Server = mongo.Server
:)