0

I simplified my code to show the problem. When I use this Coffeescript snippet:

$("<div>")
.text "hi"
.appendTo "body"

I expect it to compile like this:

$("<div>").text("hi").appendTo("body")

What it does instead is:

$("<div>").text("hi".appendTo("body"))

I found out that you can keep the brackets and it works, but I guess it's not the way you're supposed to write Coffeescript.

Can anyone tell me how I'm supposed to write it so it compiles to the desired output? Thank you very much.

4
  • I can see why the compiler would do that. You can't really expect the compiler to know what you want in that case. I suppose the language philosophy is to make a guess? Commented Aug 22, 2012 at 16:10
  • @ChaosPandion I think the compiler should do it that way it currently does if the last line would be indented... but I see your point, that's a problem with coffeescript Commented Aug 22, 2012 at 16:16
  • I don't see it as a problem really. The reason most languages require extra syntax to wrap method call arguments is to avoid such ambiguity. The fact that it is mostly optional in Coffeescript is nice but sometimes you have to help the compiler understand what you mean. Commented Aug 22, 2012 at 16:22
  • It may be tough to visualize but imagine you are parsing a potentially large amount of arguments. You reach the end of "hi" and everything is good so far. OK, now we have some white space here that's optional so I can mostly ignore it. OK so we have found a . after the first argument. Well I'm currently parsing arguments so this must be a method call on the "hi" so we begin treating the first argument as a method call. Commented Aug 22, 2012 at 16:30

3 Answers 3

4

Add the parentheses.

As far a good style goes, you should only omit syntax when it clutters your intent. In this case, omitting them loses your intent. Form follows function. You need the parentheses here inorder to declare precedent, and Coffeescript has support for them for that reason.

Sign up to request clarification or add additional context in comments.

Comments

3

I found out that you can keep the brackets and it works, but I guess it's not the way you're supposed to write Coffeescript.

Parentheses in CoffeeScript are optional, but that doesn't mean you're not supposed to use them. Feel free to use them! In some cases, like yours, they're even required.

To me, the big win with optional parentheses is for anonymous callbacks and other cases where the parentheses would otherwise span several lines, like this:

foo 'bar', (err, res) ->
  # Do stuff

Which, to me, is superior to

foo('bar', (err, res) ->
  # Do stuff
)

But even if that's your style, go for it!

So, to summarize, just write:

$("<div>")
  .text("hi")
  .appendTo("body")

Edit: Or even

$("<div>").text("hi").appendTo("body")

In this particular case, though, you could of course do:

$("<div>", text: "hi").appendTo("body")

TIMTOWDY ;)

3 Comments

OK. Not so cool, but at least I know I wasn't missing some information. Thanks!
$("<div>", text: "hi").appendTo("body") compiles to $("<div>", { text: "hi" }).appendTo("body"); ... not what you want.
@user508994: Why not? jQuery supports passing attributes as an object.
0

coco and livescript (on npm or github) both are derived from coffeescript and are more "space sensitive", which allows you to do:

$ "<div>" .text "hi" .appendTo "body"

and

$("<div>")
  .text "hi"
  .appendTo "body"

which both compile to

$("<div>").text("hi").appendTo("body");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.