LoginSignup
1
1

More than 5 years have passed since last update.

CoffeeScript vs Literate CoffeeScript

Last updated at Posted at 2013-11-21

You can write CoffeeScript inside Markdown document because the compiler, coffee, ignores everything outside code blocks.

Here are two equivalent codes in CoffeScript (.coffee) and Literate CoffeeScript (.litcoffee).

CoffeeScript

FactoryMethod.coffee
###

# Factory Method Example in CoffeeScript

## Introduction

This example of the factory method pattern is a part of a [Tic-tac-toe](http://en.wikipedia.org/wiki/Tic-tac-toe) application. See [Wikipedia](http://en.wikipedia.org/wiki/File:Factory_Method_UML_class_diagram.svg) for the UML diagram of the factory method pattern.

This example has four classes: Grid, GridCell, Board and Space.

Grid and GridCell are general purpose classes. Suppose they are provided by an external library.

Grid (Creator) doesn't know Space (ConcreteProduct) because Grid is an external library class:

###

class Grid # <<Creator>>

  @cells = []
  @row = 0
  @column = 0

  constructor: (@rows, @columns) ->
    size = @rows * @columns
    @cells = new Array(size)
    for row in [0...@rows]
      for column in [0...@columns]
        cell = this.newGridCell(row, column)
        this.cellAt row, column, cell

  newGridCell: () -> # returns GridCell
    throw "abstract method"

  cellAt: (row, column, val = null) ->
    i = (row * @columns) + column
    if val == null
      @cells[i]
    else
      @cells[i] = val

  cells: () ->
    @cells

  eachCellsInRow: (row, callback) ->
    for column in [0...@columns]
      callback this.cellAt(row, column)

  eachCellsInColumn: (column, callback) ->
    for row in [0...@rows]
      callback this.cellAt(row, column)

  each: (callback) ->
    callback cell, index for index, cell of @cells

# GridCell is an abstract grid cell, used by Grid. GridCell (Product) doesn't know Board (ConcreteCreator) because GridCell is an external library class:

class GridCell # <<Product>>

  constructor: (@row, @column) ->

# Board is a subclass of Grid. It overrides `#newGridCell` factory method:

class Board extends Grid # <<ConcreteCreator>>

  constructor: (@rows, @columns) ->
    super @rows, @columns

  newGridCell: (row, column) ->
    new Space(row, column)

# Space is a concrete GridCell, used by Board:

class Space extends GridCell # <<ConcreteProduct>>
  constructor: (@row, @column) ->
    @type = "Space"

# Here is an example:

board = new Board(3, 3)

#board.each (cell, index) ->
#  console.log cell

console.log 'each cells in row 1:'
board.eachCellsInRow 1,
  (cell, index) -> console.log cell

console.log 'each cells in columns 1:'
board.eachCellsInColumn 1,
  (cell, index) -> console.log cell

###
# Result

$ coffee FactoryMethod.litcoffee
each cells in row 1:
{ row: 1, column: 0, type: 'Space' }
{ row: 1, column: 1, type: 'Space' }
{ row: 1, column: 2, type: 'Space' }
each cells in columns 1:
{ row: 0, column: 1, type: 'Space' }
{ row: 1, column: 1, type: 'Space' }
{ row: 2, column: 1, type: 'Space' }
###

Literate CoffeeScript

FactoryMethod.litcoffee
# Factory Method Example in CoffeeScript

## Introduction

This example of the factory method pattern is a part of a [Tic-tac-toe](http://en.wikipedia.org/wiki/Tic-tac-toe) application. See [Wikipedia](http://en.wikipedia.org/wiki/File:Factory_Method_UML_class_diagram.svg) for the UML diagram of the factory method pattern.

This example has four classes: Grid, GridCell, Board and Space.

Grid and GridCell are general purpose classes. Suppose they are provided by an external library.

## Code

Grid (Creator) doesn't know Space (ConcreteProduct) because Grid is an external library class:

    class Grid # <<Creator>>

      @cells = []
      @row = 0
      @column = 0

      constructor: (@rows, @columns) ->
        size = @rows * @columns
        @cells = new Array(size)
        for row in [0...@rows]
          for column in [0...@columns]
            cell = this.newGridCell(row, column)
            this.cellAt row, column, cell

      newGridCell: () -> # returns GridCell
        throw "abstract method"

      cellAt: (row, column, val = null) ->
        i = (row * @columns) + column
        if val == null
          @cells[i]
        else
          @cells[i] = val

      cells: () ->
        @cells

      eachCellsInRow: (row, callback) ->
        for column in [0...@columns]
          callback this.cellAt(row, column)

      eachCellsInColumn: (column, callback) ->
        for row in [0...@rows]
          callback this.cellAt(row, column)

      each: (callback) ->
        callback cell, index for index, cell of @cells

GridCell is an abstract grid cell, used by Grid. GridCell (Product) doesn't know Board (ConcreteCreator) because GridCell is an external library class:

    class GridCell # <<Product>>

      constructor: (@row, @column) ->

Board is a subclass of Grid. It overrides `#newGridCell` factory method:

    class Board extends Grid # <<ConcreteCreator>>

      constructor: (@rows, @columns) ->
        super @rows, @columns

      newGridCell: (row, column) ->
        new Space(row, column)

Space is a concrete GridCell, used by Board:

    class Space extends GridCell # <<ConcreteProduct>>
      constructor: (@row, @column) ->
        @type = "Space"

Here is an example:

    board = new Board(3, 3)

    #board.each (cell, index) ->
    #  console.log cell

    console.log 'each cells in row 1:'
    board.eachCellsInRow 1,
      (cell, index) -> console.log cell

    console.log 'each cells in columns 1:'
    board.eachCellsInColumn 1,
      (cell, index) -> console.log cell

This is a result:

    ###
    $ coffee FactoryMethod.litcoffee
    each cells in row 1:
    { row: 1, column: 0, type: 'Space' }
    { row: 1, column: 1, type: 'Space' }
    { row: 1, column: 2, type: 'Space' }
    each cells in columns 1:
    { row: 0, column: 1, type: 'Space' }
    { row: 1, column: 1, type: 'Space' }
    { row: 2, column: 1, type: 'Space' }
    ###

Discussion

I want to write in literate style but there isn't enough support by editors and viewers. For example, I can't find Sublime Text 2 module for syntax highlighting. This website and its editor, Qiita and Kobito, is another example.

Who write code in Literate CoffeeScript?

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1