1

I wrote the following code, intended to join strings into a url.

_ = require 'underscore'

exports.joinUrl = (start, rest...) ->
  for item in rest
    if _.last start is '/'
      if _.first item is '/'
        start += item[1..]
      else
        start += item
    else
      if _.first item is '/'
        start += item
      else
        start += '/' + item
  start

When I start up the coffeescript repl, a very strange thing happens:

> _ = require 'underscore'
[snipped]
> {joinUrl} = require './joinurl'
{ joinUrl: [Function] }
> _
{ joinUrl: [Function] }

Huh? Somehow the import of joinUrl is overwriting the definition of the variable _. Even though (a) coffeescript wraps the module pasted above into a function, so that any usage of the variable _ shouldn't affect the outer scope, and (b) at no point in that code do I make any assignment of _, except to require 'underscore', which should be the exact same thing!

Any idea what's going on here?

limp_chimp
  • 13,475
  • 17
  • 66
  • 105

1 Answers1

5

Like in Python, the REPL makes every expression result available as _, like in

> 5
5
> _ + 3
8

Your code is translated into something like

> _ = (_ = require 'underscore')
[snipped]
> _ = ({joinUrl} = require './joinurl')
{ joinUrl: [Function] }
> _ = (_)
{ joinUrl: [Function] }
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • This is documented in the [repl.cofee docs]( http://coffeescript.org/documentation/docs/repl.html). It says that each input is assigned to `_` to force it to be an expression. – Pablo Navarro Apr 01 '14 at 17:36
  • Yikes, OK well that answers my question. Too bad that doesn't play nicely with code that uses underscore.js. – limp_chimp Apr 01 '14 at 17:37
  • 4
    @limp_chimp: Just to be clear, this is a feature of the REPL, not CoffeeScript itself. It just means that at the REPL, you'll need to use a different name for Underscore. You can still use _ in all your code. – Chuck Apr 01 '14 at 17:44