Node.js REPL eval - sockets

I am trying to implement an evaluation into a Node.JS REPL. I am getting the error TypeError: Property 'eval' of object #<REPLServer> is not a function. Here is my source code:
repl.start("> ", socket, socket, true, function(cmd, context, filename, callback){
etc...

repl.start() takes an object with those options, not individual arguments:
e.g. (note the curly brackets)
repl.start({
prompt: "node via stdin> ",
input: process.stdin,
output: process.stdout
});
see the example at: http://nodejs.org/docs/v0.8.4/api/repl.html#repl_repl_start_options

Related

Are Erlang -callbacks to be invoked only through MFA functions (apply/3, spawn/3, ...)? (Custom Behaviors HOWTO)

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"

Coffeescript member is undefined

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.

CoffeeScript and Cake Error

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']

How to detect an error in mapreduce

Let's have an "error_test.js" file that contains:
db = db.getMongo().getDB( "mydb" );
db.mycol.insert( { hello : "world" } );
print("it is shown");
db.runCommand(
{
mapReduce: "mycol",
map: function(){ print(not_exists); },
reduce: function(key, values){},
out: { replace: "myrescol" }
}
);
print("it is shown too (after error in mapreduce!)");
If I run the file (in Windows command line), I get:
mypath>mongo error_test.js
MongoDB shell version: 2.4.0
connecting to: test
it is shown
it is shown too (after error in mapreduce!)
mypath>echo %errorlevel%
0
mypath>
So we can deduce that:
the mapreduce error doesn't stop the execution.
the mapreduce error is not shown to the user.
the mapreduce error is not translated to the exit code (0 = success) (so a caller program can't detect the error).
The only way to know of the error is by looking for the following line at "mongod.log":
Wed Jun 12 10:02:37.393 [conn14] JavaScript execution failed: ReferenceError: not_exists is not defined near '(){ print(not_exists)'
Same happens if we use the "db.doEval(my_js)" method in Java and we put the content of "error_test.js" file into the "my_js" variable: The mapreduce error is not detected (no excepcion is launched, no null value is returned, "ok : 1.0" appears in the response).
So my question is: How can I detect an error in the mapreduce? (both in a js file and in the doEval() method)
Thank you
You need to capture the return document from db.runCommand() into a variable and then check its ok value in your script - you can then throw an error or print output, etc.
print("it is shown");
var res = db.runCommand(
{
mapReduce: "mycol",
map: function(){ print(not_exists); },
reduce: function(key, values){},
out: { replace: "myrescol" }
}
);
printjson(res);
if (res.ok == 0) {
print("Oopsy!");
throw("error! " + res.errmsg + " returned from mapreduce");
}
print("it is shown too (after error in mapreduce!)");

Coffeescript compilation: not as file2file, but as text2text

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]