I try to get the cake example from http://arcturo.github.io/library/coffeescript/05_compiling.html to run. But that leads to a strange error:
events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT
at errnoException (child_process.js:980:11)
at Process.ChildProcess._handle.onexit (child_process.js:771:34)
This is my Cakefile (just copied from "Little book on CoffeeSCript")
fs = require 'fs'
{print} = require 'sys'
{spawn} = require 'child_process'
build = (callback) ->
coffee = spawn 'coffee', ['-c', '-o', 'lib', 'src']
coffee.stderr.on 'data', (data) ->
process.stderr.write data.toString()
coffee.stdout.on 'data', (data) ->
print data.toString()
coffee.on 'exit', (code) ->
callback?() if code is 0
task 'build', 'Build lib/ from src/', ->
build()
I'm using Coffee 1.6.3 and node 0.10.20.
Does anyone know what I'm doing wrong?
Thanks!
ENOENT typically means "I looked for the thing you told me to find and I didn't find it". From the example page:
For example, create a file called Cakefile, and two directories, lib and src.
Do you have both of those?
I've found an explanation for what is happening here:
Using nodejs's spawn causes "unknown option -- " and "[Error: spawn ENOENT]" errors
The solution was to use exec instead of spawn
On Windows, spawn doesn't handle '.cmd' or '.bat' without file extension.
repalce
coffee = spawn 'coffee', ['-c', '-o', 'lib', 'src']
with
coffee = spwan 'coffee.cmd', ['-c','-o','lib','src']
Related
That's my suspicion as this simple code
-module(simple_server).
-export( [sayHello/0] ).
-callback say(Num :: term()) -> term().
sayHello() ->
io:fwrite( "Hello 1: ~p\n", [ say(1) ]) ,
io:fwrite( "Hello 2: ~p\n", [ say(2) ]) .
fails to be compiled:
$ erlc simple_server.erl
simple_server.erl:7: function say/1 undefined
simple_server.erl:8: function say/1 undefined
If that is the case, then this is not explicitly commented elsewhere:
official docs, "learn erlang", this answer.
You need to provide the name of the callback module, which can be done through apply and spawn, but you can also make a simple call using a variable as the module name, e.g. CallbackModule:say(1).
So you could do either:
sayHello(CallbackModule) ->
io:fwrite( "Hello 1: ~p\n", [ CallbackModule:say(1) ]) ,
io:fwrite( "Hello 2: ~p\n", [ CallbackModule:say(2) ]) .
or
sayHello(CallbackModule) ->
io:fwrite( "Hello 1: ~p\n", [ apply(CallbackModule, say, [1]) ]) ,
io:fwrite( "Hello 2: ~p\n", [ apply(CallbackModule, say, [2]) ]) .
Those two versions are equivalent.
Let's create a callback module implementing the simple_server behaviour:
-module(my_callback).
-behaviour(simple_server).
-export([say/1]).
say(N) ->
{N, is, the, loneliest, number}.
Now we can call simple_server:sayHello with the module name as the argument:
> simple_server:sayHello(my_callback).
Hello 1: {1,is,the,loneliest,number}
Hello 2: {2,is,the,loneliest,number}
HOWTO Erlang Custom Behaviors (template method pattern).
-1. Write a generic module. Here, an algorithm is defined, but some steps (callback functions in Erlang nomenclature) are left for a future specific definition.
%% generic.erl
-module(generic).
-export( [sayHello/1] ).
-callback say(Num :: term()) -> term(). %% future definition
%% generic algorithm: needs the reference to the provider module
sayHello(ProviderModule) ->
io:fwrite( "Hello 1: ~p\n", [ ProviderModule:say(1) ]) ,
io:fwrite( "Hello 2: ~p\n", [ ProviderModule:say(2) ]) .
-2. Compile generic.erl
erlc generic.erl
-(3.) Try to write a provider (callback) module
%% callbacks1.erl (fails to implement say/1 callback)
-module( callbacks1 ).
-behaviour( generic ).
-(4.) Compile callbacks1.erl: use -pa . to say where generic.beam is. (Therefore, the expected warning about say/1 is issued).
erlc -pa . callbacks1.erl
callbacks1.erl:2: Warning: undefined callback function say/1 (behaviour 'generic')
(Note: If -pa is not given, you'll got this: "callbacks1.erl:2: Warning: behaviour generic undefined")
-3. Write a correct provider (callback) module.
%% callbacks2.erl
-module( callbacks2 ).
-behaviour( generic ).
-export( [say/1] ).
say(1) -> "good morning";
say(2) -> "bon jour";
say(_) -> "hi".
-4. Compile it
erlc -pa . callbacks2.erl
(Ok now).
-5. Write a main.erl to gather generic module with callback module.
%% main.erl
-module( main ).
-export( [main/0] ).
main() ->
%% call the generic algorithm telling it what callback module to use
generic:sayHello( callbacks2 )
. % ()
-6. Compile and run main
erlc main.erl
erl -noshell -s main main -s init stop
We get:
Hello 1: "good morning"
Hello 2: "bon jour"
Taking a look at the following segment of code you will see two cases where the sencha cmd return an error and one case that it doesn't
var memoryStore = new MemoryStore<Individual>("personnel", [
'name', 'email', 'phone'
], [
new Individual("Batman", "etsigoustaro#thefirm.com", "+306969696969"),
new Individual("Jean Luc", "jeanluc.picard#enterprise.com", "555-111-1111"),
new Individual("Worf", "worf.moghsson#enterprise.com", "+30 696 969 6969"),
new Individual("Deanna", "mr.data#enterprise.com", "+30 6969696969"),
new Individual("Data", "deanna.troi#enterprise.com", "+30-6969696969"),
])
//memoryStore.toExtJS()
Ext.define('extTestTs.store.Personnel', (function(){
//return JSON.stringify(memoryStore.toExtJS()) //fails
//return Ext.Object.merge({},{}) //fails
return {} //succeeds
})());
As you see we have removed everything, even extends is missing but as long as you are typing an object by hand it works. When this object is returned from a function it stops to work!
What does the sencha cmd does behind the scenes? Is it parsing the plain javascript as a text file?..
Because if it was javascript it would run without an issue.
This is the error from sencha cmd console output:
[ERR] C2008: Requirement had no matching files (extTestTs.store.Personnel) -- /home/student/Desktop/Typescript/extTestTs/classic/src/view/main/List.js:8:10
[ERR]
[ERR] BUILD FAILED
[ERR] com.sencha.exceptions.ExBuild: Failed to find any files for /home/student/Desktop/Typescript/extTestTs/classic/src/view/main/List.js::ClassRequire::extTestTs.store.Personnel
[ERR]
[ERR] Total time: 3 seconds
[ERR] The following error occurred while executing this line:
/home/student/bin/Sencha/Cmd/6.1.2.15/plugins/ext/current/plugin.xml:425: The following error occurred while executing this line:
/home/student/Desktop/Typescript/extTestTs/.sencha/app/build-impl.xml:380: The following error occurred while executing this line:
/home/student/Desktop/Typescript/extTestTs/.sencha/app/init-impl.xml:382: com.sencha.exceptions.ExBuild: Failed to find any files for /home/student/Desktop/Typescript/extTestTs/classic/src/view/main/List.js::ClassRequire::extTestTs.store.Personnel
How could we overcome this restriction of explicitly defining the object and rather define it more dynamically?
The goal is to make typescript work with ExtJS but not with the extreme unconventional solutions others propose, like forking typescript itself
Found a workaround
First allow unreachable code in typescript
Here is a screenshot from the IntelliJ settings:
And the code in the questions transforms into that
var memoryStore = new MemoryStore<Individual>("personnel", [
'name', 'email', 'phone'
], [
new Individual("Batman", "etsigoustaro#thefirm.com", "+306969696969"),
new Individual("Jean Luc", "jeanluc.picard#enterprise.com", "555-111-1111"),
new Individual("Worf", "worf.moghsson#enterprise.com", "+30 696 969 6969"),
new Individual("Deanna", "mr.data#enterprise.com", "+30 6969696969"),
new Individual("Data", "deanna.troi#enterprise.com", "+30-6969696969"),
])
//memoryStore.toExtJS()
Ext.define('extTestTs.store.Personnel', function (Personnel) {
return memoryStore.toExtJS()
return {} //do not erase this line
});
Yeah the line return {} might seem totally redundant but (obviously) the sencha cmd is trying to parse the file before it includes it in the requires
Now sencha cmd gives a success and executing sencha app web start the sample app works ok
I get the following error:
Uncaught TypeError: Cannot call method 'push' of undefined
In the next code:
class classDemo
names : ['t1', 't2']
methodM1: () ->
# This works:
#names.push 't3'
console.log #names.toString()
#socket = io.connect()
#socket.on 'connect', () ->
# This raise the error:
#names.push 't4'
console.log #names.toString()
Does anyone know how to push into "names" inside the socket.on method? (How to push 't4' correctly?
Thanks
EDIT: The solution proposed by #Sven works for one level of chaining. It seems to fail for two chained calls. Please consider the following example:
methodM1: () ->
_this = #
#socket = io.connect() # connect with no args does auto-discovery
#socket.on 'connect', () ->
# This works:
_this.names.push 'inside connect'
console.log _this.names.toString()
#socket.emit 'getModels', (data) ->
# This does not work:
_this.names.push 'inside emit'
console.log _this.names.toString()
I tried to apply the same solution again inside connect and before emit (see below) but I get no output:
_this2 = _this
#socket.emit 'getModels', (data) ->
_this2.names.push "inside emit"
console.log _this2.names.toString()
Thanks.
your emit is never fired because emit sends data and requieres therefore a datastructure.
Please change your code like this
a) use the fat arrow
b) emit a data structure
methodM1: ->
#socket = io.connect()
#here use the fat arrow it does the '_this = # automatically'
#socket.on 'connect', =>
#names.push 'inside connect'
console.log _this.names.toString()
#socket.emit 'getModels', yo: "got your message"
The fat arrow always binds to the outer instance (see When does the "fat arrow" (=>) bind to "this" instance)
I am not sure (well, I am pretty sure but havent tried it) that you can send a closure over the wire.
We can compile coffescript file to js-file with command:
coffee --join path/to/result.js --compile path/to/coffeescript_dir/
But what if I want to compile a piece of coffeescript code (as text) and get piece of js code (as a text too), and they are not files.
For example:
cs text: "func = () -> 55"
js text result: "var func; func = function(){return 55;}"
It must be done from console, or even better from python interactive console :)
You can use --eval to take a string parameter as coffee input, --bare to avoid the JS output being wrapped in a closure, and --print to print the output on stdout instead of a file:
$ coffee --print --bare -eval 'func = -> 55'
var func;
func = function() {
return 55;
};
To call it from Python, you can use the subprocess module:
from subprocess import Popen, PIPE
def compile_cs(cs_code):
args = ['coffee', '--print', '--bare', '--eval', cs_code]
return Popen(args, stdout=PIPE).communicate()[0]
I'm writing a (ever larger) set of unit tests using Coffeescript and node.js. I build the files using the coffee "watch" option (-w)
coffee -w -b -c -o web/ src/
My problem is that running the unit tests takes 20 secs (I'm assuming for the compile to .js).
If possible, I'd like automatically run the unit tests on a (compiled .js) file change, which would eliminate the long wait for the results.
My current Cakefile:
fs = require 'fs'
{print} = require 'sys'
{spawn, exec} = require 'child_process'
build = (watch, callback) ->
if typeof watch is 'function'
callback = watch
watch = false
options = ['-c', '-b', '-o', 'web', 'src']
options.unshift '-w' if watch
coffee = spawn 'coffee', options
coffee.stdout.on 'data', (data) -> print data.toString()
coffee.stderr.on 'data', (data) -> print data.toString()
coffee.on 'exit', (status) -> callback?() if status is 0
task 'test', 'Run the test suite', ->
build ->
require.paths.unshift __dirname + "/lib"
{reporters} = require 'nodeunit'
process.chdir __dirname
reporters.default.run ['test']
Take a look at the Cakefile for my connect-assets project: https://github.com/adunkman/connect-assets/blob/master/Cakefile
It's a bit more complex than sstephenson's (which I assume your example is derived from), but it shows how you can watch a directory of files for changes and respond to those changes by re-running tests.