CoffeeScript a-zA-Z




        Vyacheslav Voronchuk

     voronchuk@wm-software.com
           Skype: voronhukvk
  http://ua.linkedin.com/in/voronchuk/
Pattern-matching
# Variable swaps
[a, b] = [b, a]
# Variable declaration
[fname, lname, sname] =
    ['Vyacheslav', 'Voronchuk', 'Kazimirovich']

alert "#{lname} #{fname} #{sname}"
# Variable declaration with splats
[first, other..., last] = [1,2,3,4,5,6,7]

alert "#{first} #{JSON.stringify(other)} #{last}"
# Object matching
coords =
    x: 150
    y: 100
    z: 5
{ x: declaredX, y: declaredY, z: declaredZ } = coords
alert "#{declaredX}, #{declaredY}, #{declaredZ}"
person =
    fname: 'Vyacheslav'
    lname: 'Voronchuk'
    languages: [
         'Russian'
         'English'
         'Ukranian'
         'French'
         'German'
    ]
    coding: [
         'javascript', 'php'
         'ruby', 'python'
         'erlang', 'clojure'
         'C++', 'Pascal'
         'ML'
    ]
{
    fname: name,
    languages: [bestLang, other..., worstLang],
    coding: [loveCode]
} = person
alert "#{name} speaks #{bestLang} and have some expirience
in #{worstLang}.
He likes to code with the help of #{loveCode}"
# (coords, 3dPoint, options) ->
move = ([x, y, z], object, { animate: anim, type: type }) ->

    alert "Move #{object} to (#{x} #{y} #{z}) with options:
        animate: #{anim}
        animation type: #{type}"


move [100,200,5],
    'Point object',
    animate: true
    type: 'slide'
OOP style in CoffeeScript
class Page
    constructor: (@title, @description, @rawComments, { canCopy: @canCopy, hidden: @hidden }) ->
        Page.totalPages++
        alert "Article '#{title}' about '#{description}'"

    # Prototype properties
    copy: ->
        if @canCopy then new Page @title, @description, @rawComments,
             canCopy: @canCopy
             hidden: @hidden
        else
             throw 'Sorry, access denied'
    hide: -> @hidden = true unless @hidden

    # Class-level properties
    @totalPages: 0
    @count: -> alert @totalPages

NewPage = new Page 'Coffeescript a-zA-Z',
    'Advanced features provided by CoffeeScript'
    []
    canCopy: true
    hidden: false
NewPage.copy()
Page.count()
class Container
    constructor: (@children = []) ->

    addChild: (child) ->
        child.parentContainer = @
        @children[@children.length] = child

    removeChild: (child) ->
        @children = (item for item in @children when item != child)
        child.parentContainer = null

class Containable extends Container
    constructor: (parentContainer, children) ->
        if children then super children else super()
        parentContainer.addChild @ if parentContainer

    remove: -> @parentContainer.removeChild @ if @parentContainer

    moveTo: (newContainer) ->
        @remove()
        newContainer.addChild @


class Comment extends Containable
    constructor: (@text, parentContainer) ->
        super parentContainer if parentContainer
    getText: -> @text

class Page extends Container


Page1 = new Page
Comment1 = new Comment 'Root comment', Page1
alert "Childrens: #{Page1.children.length}"
Comment2 = new Comment 'Nested comment', Comment1
Comment2.moveTo Page1
alert "Childrens: #{Page1.children.length}"
class Container
    constructor: (@children = []) ->

      addChild: (child) ->
          unless child instanceof Containable then throw 'Invalid child type'
          child.parentContainer = @
          @children[@children.length] = child
    removeChild: (child) ->
        unless child instanceof Containable then throw 'Invalid child type'
        @children = (item for item in @children when item != child)
        child.parentContainer = null
class Containable extends Container
    constructor: (parentContainer, children) ->
        if children then super children else super()
        parentContainer.addChild @ if parentContainer

      remove: -> @parentContainer.removeChild @ if @parentContainer
    moveTo: (newContainer) ->
        unless newContainer instanceof Container then throw 'Invalid container type'
        @remove()
        newContainer.addChild @
class Comment extends Containable
    constructor: (@text, parentContainer) ->
        super parentContainer if parentContainer

      getText: => @text

class Page extends Container
class Author

try
    Page1 = new Page
    Author1 = new Author
    Page1.addChild Author1
catch e
    alert e
Comment1 = new Comment 'Root comment', Page1
alert Comment1.getText.call window
extend = (obj, mixin) ->
    obj[name] = method for name, method of mixin
    obj

Container =
    addChild: (child) ->
        child.parentContainer = @
        @children[@children.length] = child
    removeChild: (child) ->
        @children = (item for item in @children when item != child)
        child.parentContainer = null

Containable =
    remove: -> @parentContainer.removeChild @ if @parentContainer
    moveTo: (newContainer) ->
        @remove()
        newContainer.addChild @


class Comment
    extend Comment::, Container
    extend Comment::, Containable

    constructor: (@text, parentContainer, @children = []) -> parentContainer.addChild @ if parentContainer

    getText: => @text

class Page
    extend Page::, Container

    constructor: (@children = []) ->


Page1 = new Page
Comment1 = new Comment 'Root comment', Page1
alert "Childrens: #{Page1.children.length}"
Comment2 = new Comment 'Nested comment', Comment1
Comment2.moveTo Page1
alert "Childrens: #{Page1.children.length}"
moduleKeywords = ['extended', 'included']
class Module
    @extend: (obj) ->
        for key, value of obj when key not in moduleKeywords
             @[key] = value

        obj.extended?.apply(@)
        this
    @include: (obj) ->
        for key, value of obj when key not in moduleKeywords
            # Assign properties to the prototype
            @::[key] = value

        obj.included?.apply(@)
        this

# Example
classProperties =
    find: (id) ->
    create: (attrs) ->
instanceProperties =
    save: ->

class User extends Module
    @extend classProperties
    @include instanceProperties

    user = User.find(1)

    user = new User
    user.save()

# Callbacks
ORM =
    find: (id) ->
    create: (attrs) ->
    extended: ->
        @include
        save: ->

class User extends Module
    @extend ORM
Build CoffeeScript
$ coffee --compile --output lib/ src/
$ coffee --watch --compile script.coffee
$ coffee -o lib/ -cw src/


   Asset managers: RoR, Assetic for PHP
   ect

   Grunt.js
   RequireJS with "cs" plugin

   Cakefile
References
CoffeeScript official page
The Little Book on CoffeeScript

CoffeeScript: Accelerated JavaScript
Development, by Trevor Burnham
Thank you!


      Vyacheslav Voronchuk




     http://wm-software.com/

   voronchuk@wm-software.com
         Skype: voronhukvk
http://ua.linkedin.com/in/voronchuk/

Coffeescript a z

  • 1.
    CoffeeScript a-zA-Z Vyacheslav Voronchuk voronchuk@wm-software.com Skype: voronhukvk http://ua.linkedin.com/in/voronchuk/
  • 2.
  • 3.
    # Variable swaps [a,b] = [b, a] # Variable declaration [fname, lname, sname] = ['Vyacheslav', 'Voronchuk', 'Kazimirovich'] alert "#{lname} #{fname} #{sname}" # Variable declaration with splats [first, other..., last] = [1,2,3,4,5,6,7] alert "#{first} #{JSON.stringify(other)} #{last}" # Object matching coords = x: 150 y: 100 z: 5 { x: declaredX, y: declaredY, z: declaredZ } = coords alert "#{declaredX}, #{declaredY}, #{declaredZ}"
  • 4.
    person = fname: 'Vyacheslav' lname: 'Voronchuk' languages: [ 'Russian' 'English' 'Ukranian' 'French' 'German' ] coding: [ 'javascript', 'php' 'ruby', 'python' 'erlang', 'clojure' 'C++', 'Pascal' 'ML' ] { fname: name, languages: [bestLang, other..., worstLang], coding: [loveCode] } = person alert "#{name} speaks #{bestLang} and have some expirience in #{worstLang}. He likes to code with the help of #{loveCode}"
  • 5.
    # (coords, 3dPoint,options) -> move = ([x, y, z], object, { animate: anim, type: type }) -> alert "Move #{object} to (#{x} #{y} #{z}) with options: animate: #{anim} animation type: #{type}" move [100,200,5], 'Point object', animate: true type: 'slide'
  • 6.
    OOP style inCoffeeScript
  • 7.
    class Page constructor: (@title, @description, @rawComments, { canCopy: @canCopy, hidden: @hidden }) -> Page.totalPages++ alert "Article '#{title}' about '#{description}'" # Prototype properties copy: -> if @canCopy then new Page @title, @description, @rawComments, canCopy: @canCopy hidden: @hidden else throw 'Sorry, access denied' hide: -> @hidden = true unless @hidden # Class-level properties @totalPages: 0 @count: -> alert @totalPages NewPage = new Page 'Coffeescript a-zA-Z', 'Advanced features provided by CoffeeScript' [] canCopy: true hidden: false NewPage.copy() Page.count()
  • 8.
    class Container constructor: (@children = []) -> addChild: (child) -> child.parentContainer = @ @children[@children.length] = child removeChild: (child) -> @children = (item for item in @children when item != child) child.parentContainer = null class Containable extends Container constructor: (parentContainer, children) -> if children then super children else super() parentContainer.addChild @ if parentContainer remove: -> @parentContainer.removeChild @ if @parentContainer moveTo: (newContainer) -> @remove() newContainer.addChild @ class Comment extends Containable constructor: (@text, parentContainer) -> super parentContainer if parentContainer getText: -> @text class Page extends Container Page1 = new Page Comment1 = new Comment 'Root comment', Page1 alert "Childrens: #{Page1.children.length}" Comment2 = new Comment 'Nested comment', Comment1 Comment2.moveTo Page1 alert "Childrens: #{Page1.children.length}"
  • 9.
    class Container constructor: (@children = []) -> addChild: (child) -> unless child instanceof Containable then throw 'Invalid child type' child.parentContainer = @ @children[@children.length] = child removeChild: (child) -> unless child instanceof Containable then throw 'Invalid child type' @children = (item for item in @children when item != child) child.parentContainer = null class Containable extends Container constructor: (parentContainer, children) -> if children then super children else super() parentContainer.addChild @ if parentContainer remove: -> @parentContainer.removeChild @ if @parentContainer moveTo: (newContainer) -> unless newContainer instanceof Container then throw 'Invalid container type' @remove() newContainer.addChild @ class Comment extends Containable constructor: (@text, parentContainer) -> super parentContainer if parentContainer getText: => @text class Page extends Container class Author try Page1 = new Page Author1 = new Author Page1.addChild Author1 catch e alert e Comment1 = new Comment 'Root comment', Page1 alert Comment1.getText.call window
  • 10.
    extend = (obj,mixin) -> obj[name] = method for name, method of mixin obj Container = addChild: (child) -> child.parentContainer = @ @children[@children.length] = child removeChild: (child) -> @children = (item for item in @children when item != child) child.parentContainer = null Containable = remove: -> @parentContainer.removeChild @ if @parentContainer moveTo: (newContainer) -> @remove() newContainer.addChild @ class Comment extend Comment::, Container extend Comment::, Containable constructor: (@text, parentContainer, @children = []) -> parentContainer.addChild @ if parentContainer getText: => @text class Page extend Page::, Container constructor: (@children = []) -> Page1 = new Page Comment1 = new Comment 'Root comment', Page1 alert "Childrens: #{Page1.children.length}" Comment2 = new Comment 'Nested comment', Comment1 Comment2.moveTo Page1 alert "Childrens: #{Page1.children.length}"
  • 11.
    moduleKeywords = ['extended','included'] class Module @extend: (obj) -> for key, value of obj when key not in moduleKeywords @[key] = value obj.extended?.apply(@) this @include: (obj) -> for key, value of obj when key not in moduleKeywords # Assign properties to the prototype @::[key] = value obj.included?.apply(@) this # Example classProperties = find: (id) -> create: (attrs) -> instanceProperties = save: -> class User extends Module @extend classProperties @include instanceProperties user = User.find(1) user = new User user.save() # Callbacks ORM = find: (id) -> create: (attrs) -> extended: -> @include save: -> class User extends Module @extend ORM
  • 12.
    Build CoffeeScript $ coffee--compile --output lib/ src/ $ coffee --watch --compile script.coffee $ coffee -o lib/ -cw src/ Asset managers: RoR, Assetic for PHP ect Grunt.js RequireJS with "cs" plugin Cakefile
  • 13.
    References CoffeeScript official page TheLittle Book on CoffeeScript CoffeeScript: Accelerated JavaScript Development, by Trevor Burnham
  • 14.
    Thank you! Vyacheslav Voronchuk http://wm-software.com/ voronchuk@wm-software.com Skype: voronhukvk http://ua.linkedin.com/in/voronchuk/