CoffeeScript: coffee -w name-of-file.coffee complains: “window is not defined” - coffeescript

In CofeeScript I am creating a global object by doing this:
window.App =
init : ->
...
Running coffee -w app.coffee complains window is not defined and doesn't rewrite the app.js file.
However, running coffee -c app.coffee compiles without a problem.
How can I get coffee -w to accept global window?
CoffeeScript version is 1.1.1 (from coffee -v)
Thanks!

If you want to watch a file and have it compiled you need to do:
coffee -wc file.coffee
Using only the -w flag causes coffee to just run the script when it changes, as if you had run: coffee file.coffee
In regards to the window is not defined error, if you want to make your script runnable both in a browser and in node.js, then you can do this:
root = exports ? this
class Thing
constructor: (#name) ->
whoAreYou: ->
alert #name
root.Thing = Thing
Another useful flag combination is -wp which just pipes the compile javascript to standard out each time you make a change to the file.

Related

Command-line input with Sys.stdin() not working in Haxe

I'm trying to use the input function from the Sys class, but when I run the build and the prompt occurs, I'm unable to enter any input. What alternatives are there to Sys, or what ought I do to resolve this? I've checked Haxelib and haven't found anything that I think can be used.
For reference, what I have written:
Sys.println("First player's name: ");
var p1:String = Sys.stdin().readLine();
My hxml args:
-main Main.hx
-cp src
-cp src/cards
-cp src/cards/library
-lib Random
-neko test.n
-cmd neko test.n
It works fine if you manually start the generated test.n instead of doing that via -cmd in the hxml. I suspect that the Haxe process does not direct input to the stdin of the -cmd process or something like that.
If you still want to compile and run at the same time, I recommend creating a little .bat (or .sh if you're on Linux) script for this:
haxe build.hxml
neko test.n

can I attach functions to the coffee console before it starts?

Let's say I want to have a pp function:
coffee> pp = (obj) -> JSON.stringify(obj)
[Function]
coffee> pp({cat: "fancy"})
'{"cat":"fancy"}'
coffee>
Is there a way that I can have that function be available immediately when the console loads? I'm looking at coffee -r "utils.coffee", but don't see any way to put that required library into an object that's available at the command line. It looks like I might be able to alter repl.js, but that seems like a bad idea.
You can put those functions into the global variable (which is kinda Node's version of window) and then use the -r option.
# utils.coffee
global.pp = (obj) -> JSON.stringify(obj)
And then run, on the same directly utils.coffee of:
coffee -r ./utils
It should start a CoffeeScript REPL and have the pp function available as a global variable:
coffee> pp ohmy: 'neat'
'{"ohmy":"neat"}'
Update: it seems the -r command-line option was removed in CoffeeScript's master. It probably wasn't meant to be used this way :(
Update 2: There's another way to do this! And it doesn't rely on any command-specific parameter:
{ echo "require './utils'"; cat; } | coffee
It will, however, not work 100% like the Coffee REPL. The arrow keys for example don't seem to work.
Edit (jc): Using this method allows you to make an unload for node, which is handy:
# utils.coffee
global.unload = (moduleName) ->
cacheName = require.resolve(moduleName)
delete require.cache[cacheName]
$ coffee -r ~/Dev/utils.coffee
coffee> unload
[Function]
Update 3: Another possibility is to "create your own REPL". Not really reimplementing anything. Based on this hacky solution, you could do something like:
#! /usr/bin/env coffee
# REPL functions.
global.pp = (obj) -> JSON.stringify(obj)
# Start the REPL.
require 'coffee-script/lib/coffee-script/repl'
And then use that script as your new REPL. It will work exactly like the normal Coffee REPL plus the new functions (no problems with arrow keys nor TAB completion :)
BTW, i think you'll need to have CoffeeScript installed without the -g option on npm for that to work.
It is a very hacky solution though. It relies on the internal CoffeeScript implementation file structure and its functionality, and that could change at any moment (in fact, i'm aware that there has been some work done in a new revamped Coffee REPL based on Node's one... i hope that functionality gets exposed to be used programmatically, so these kind of hacks are not hacks any more).
Have a look at #Daniel's (Daniel Taylor's) excellent nesh, an enhanced node shell that also speaks CoffeeScript: http://danielgtaylor.github.io/nesh/
Here's how you would load your pp function into a CoffeeScript REPL:
nesh -c -e 'pp = (obj) -> JSON.stringify(obj)'
Similarly, if you wanted to load a file, say ~/.nesh_profile.coffee (analogous to loading a shell profile), on startup, use:
nesh -c -e ~/.nesh_profile.coffee
Small caveat: The REPL language - JavaScript v. CoffeeScript - and the language of the code you're loading must be the same. Edit: The only exception is that you can always load JavaScript via a file with extension .js, even when starting a CoffeeScript REPL. (By contrast, you can't specify a JS string when starting a CoffeeScript REPL).
To automate loading of your 'nesh profile' into a CoffeeScript REPL you could define an alias in your shell profile; e.g.:
alias neshc='nesh -c -e ~/.nesh_profile.coffee'
Update: Here's how you can use the very same 'nesh profile' with a JavaScript REPL; compilation to JavaScript is performed on the fly using process substitution:
alias neshj='nesh -e <(coffee -bp ~/.nesh_profile.coffee)'
nesh is available as an npm package, so you can easily install it as follows:
sudo npm install nesh -g

Run Coffeescript Interactive (REPL) with a script

In python, I can run a script and enter interactive mode in the context of that script. This lets me mess with global variables and what not to examine program state.
$ python -i hello.py
Can I do this with Coffeescript? I've tried the following:
$ coffee -i hello.coffee
doesn't load hello.coffee. It's equivalent to coffee -i
$ cat hello.coffee | coffee -i
runs the script line by line in REPL but ends REPL after the EOF.
I've recently started a project to create an advanced interactive shell for Node and associated languages like CoffeeScript. One of the features is loading a file or string in the context of the interpreter at startup which takes into account the loaded language.
http://danielgtaylor.github.com/nesh/
Example:
# Load a string
nesh -c -e 'hello = (name) -> "Hello, #{name}"'
# Load a file
nesh -c -e hello.coffee
Then in the interpreter you can access the hello function. Also a good idea to create an alias in bash:
alias cs='nesh -c'
cat foo.coffee - | coffee -i
tells cat to first output your code and then output stdin, which gives you what you're looking for I think.
I am confronted with this problem as well. The one provide by #int3 doesn't solve this problem, for CoffeeScript is one indentation based language. stdin will pass the code line by line, but the repl is not smart enough to realize this. Since you post this question, I suggest you create one issue (feature request) on CoffeeScript

Erlide: how to set start module in run configuration?

I have problem with setting start module and function in "Run configuration"
I'm doing it that way:
"Run -> Run Configuration" and in "start" section I'm setting
Module: mod,
Function: hello
my code:
-module(mod).
-export([hello/0]).
hello()-> io:format("42").
Now, when I hit "Run" I would like mod:hello() to be execute automatically, but it doesn't work.
What am I doing wrong?
The code does get executed...
When you hit "Run", mod:hello() does get executed. The thing is, the execution of mod:hello() is meant for system initialization, like loading library code and initializing looping states. The side effect of mod:hello(), which is the string "42" as stdout will not be reflected in your Eclipse console. To prove my point, we can create some more explicit and more persistent side effects, like creating a file in the file system called output_file.txt. Change mod.erl to something like this:
-module(mod).
-export([hello/0]).
hello() ->
os:cmd("touch output_file.txt").
Hit "Run", and you will find a output_file.txt file being created under your workspace directory. This is an evidence for the execution of mod:hello().
To achieve what you want...
In an Unix shell:
$ erlc mod.erl
$ erl -noshell -s mod hello -s init stop
42
Depending on what you want to execute, there is an alternative to the answer above: the "live expressions". There is a view with this name in the same place as the console, where you can enter an expression and enable it for evaluation every time a module is recompiled.
This works nicely for expression that aren't heavy to evaluate and that are without side effects, can be used as a form of alternative to having a test suite.

Getting rid of CoffeeScript's closure wrapper

How can I omit the automatic closure wrappers that hides my variables from the global scope?
(function() {
// my compiled code
}).call(this);
Just playing around with CoffeeScript+SproutCore, and of course, I'd prefer to leave the scope as it is: in this case there is no need to protect anything from overwriting.
I know I can use # or this. at the declaration, but that's not too elegant.
Quick and dirty solution: Use the console flag -b (bare). Warning: Kittens will die if you do that!
Clean solution: Don't do that.
Usage: coffee [options] path/to/script.coffee
-c, --compile compile to JavaScript and save as .js files
-i, --interactive run an interactive CoffeeScript REPL
-o, --output set the directory for compiled JavaScript
-j, --join concatenate the scripts before compiling
-w, --watch watch scripts for changes, and recompile
-p, --print print the compiled JavaScript to stdout
-l, --lint pipe the compiled JavaScript through JSLint
-s, --stdio listen for and compile scripts over stdio
-e, --eval compile a string from the command line
-r, --require require a library before executing your script
-b, --bare compile without the top-level function wrapper
-t, --tokens print the tokens that the lexer produces
-n, --nodes print the parse tree that Jison produces
--nodejs pass options through to the "node" binary
-v, --version display CoffeeScript version
-h, --help display this help message
I used another option which was to attach my global variables to the global object in the scope of my function. I attached mine to the 'window'. This keeps your JavaScript encapsulated and only exposes the variable that you need in the global scope.