我本人写的中文版的MoonScript文档,直接看官方文档其实,还是会不得要领。后面的英文部分,就是官方的,前面是中文自己写的。

国内用MoonScript的用户相对比较少,作者leafo创作了moonscript,另外还用moonscript创作的一个lua web框架:lapis。估计moonscript想在国内普及还需要一段路要走。

Coffescript是一种中间的脚本,可以把这种脚本翻译成JavaScript。而MoonScript,是可以翻译成lua语言的中间脚本。
本文简单的介绍的:

  1. 如何在VIM中,实现MoonScript语法高亮。

  2. 如何简单的编译MoonScript脚本。

1.安装MoonScript

sudo luarocks install moonscript

2.创建.moon源文件 # app.moon

lapis = require "lapis"   
class extends lapis.Application   
  "/": => 
"Welcome to Lapis #{require "lapis.version"}!" 

3.安装MoonScript语法高亮的插件。 # **3-1.下载vim的bundle插件管理程序。

git clone VundleVim/Vundle.vim ~/.vim/bundle/vundle

3-2.创建.vimrc配置文件。

vim ~/.vimrc

3-3. 编辑.vimrc文件内容。

set nocompatible                                                                                                                      
filetype off                                                                                                                          
set rtp+=~/.vim/bundle/vundle/                                                                                                        
call vundle#rc()                                                                                                                                      
Bundle 'leafo/moonscript-vim'                                                                                                         
syntax enable 

3-4.进入VIM,安装bundle插件。

vim +BundleInstall

3-5.翻译成lua脚本,并运行。

moonc app.moon
lua app.lua

按照如上步骤操作后:

  1. 可以用moonc命令翻译.moon脚本到.lua脚步。

  2. vim支持moonscript的语法高亮检查。

Moonscript与OO面向对象:
讲MoonScript不能不提她对OO面向对像的支持,下面简单介绍一下MoonScirpt面像对像的 特性。对向函数与变量的封装,MoonScirpt的函数定义有其独特的地方是。

foo = ->
    print "foo"
foo()    --函数调用

上面是无参数函数调用,没有形参,下面是加入形参的函数声明:

foo(x, y) =>
   return x + y
ret = foo 1,5

MoonScript的函数调用,可以不使用(),省着去括号。
接下来,用类封装函数和成员表量,用一个单根继承两类做说明。

class CandyLab 
    @metadata: "Candy Lab"
class Candy extends CandyLab
  @name: "Candy"
  @value: "From CandyLab"
  @func1: =>
        print @name
        print @value + 6
        print "func1"
  @func2: (x, y) =>
        print x + y
        return x + y
  @func3: =>
        print "ok"
        print "#{@metadata}"

MoonScirpt的对象变量和函数可能直接在外部调用:

Candy\func1!
ret = Candy\func2 1,5 
Candy\func3!

在Candy类中的func3,直接引用的父类的变量metadata,另一个比较独特的地方是,用!表 示调用无参函数。MoonScript的类继承关键还是与Java接近extends。
下面是没有继承关系的两个类之间的函数调用与变量引用,而在引用的过程中有一个特别 一点的表量类型声明,就是Table类型。

class CandyLab 
    endpoints: 1
    tbl_url: {
             url_1:"http://host.com/1",
             url_2:"http://host.com/2",
             url_3:"http://host.com/3"
         }
class Candy
    @func1: =>
        print(Common.endpoints)  
        print(type(Common.tbl_url["ur1_1"]))

上面的操作是直接在Candy类中调用CandyLab的变量,其实就是没有权限访问。MoonScript 的OO特性比较常用如上,MoonScript这些特性,如果用来做Web开发,效率相对Lua来说还是 高的,而目前用MoonScript实现的最大的一个项目就是Lua框架Lapis,接下来可以看看Lapis 中是如何使用MoonScript的特性的。

作者:糖果
PS:转载到其它平台请注明作者姓名及原文链接,请勿用于商业用途。

{
target: “reference/standard_lib”
template: “reference”
title: “Standard Library”
short_name: “stdlib”
}

The MoonScript installation comes with a small kernel of functions that can be
used to perform various common things.

The entire library is currently contained in a single object. We can bring this
moon object into scope by requiring "moon".

moon = require "moon"
-- `moon.p` is the debug printer
moon.p { hello: "world" }

If you prefer to just inject all of the functions into the current scope, you
can require "moon.all" instead. The following has the same effect as above:

require "moon.all"
p { hello: "world" }

All of the functions are compatible with Lua in addition to MoonScript, but
some of them only make sense in the context of MoonScript.

MoonScript Standard Library

This is an overview of all the included functions.
All of the examples assume that the standard library has been included with
require "moon.all".

Printing Functions

p(arg)

Prints a formatted version of an object. Excellent for inspecting the contents
of a table.

Table Functions

run_with_scope(fn, scope, [args...])

Mutates the environment of function fn and runs the function with any extra
arguments in args.... Returns the result of the function.

The environment of the function is set to a new table whose metatable will use
scope to look up values. scope must be a table. If scope does not have an
entry for a value, it will fall back on the original environment.

my_env = {
  secret_function: -> print "shhh this is secret"
  say_hi: -> print "hi there!"
}

say_hi = -> print "I am a closure"

fn = ->
  secret_function!
  say_hi!

run_with_scope fn, my_env

Note that any closure values will always take precedence against global name
lookups in the environment. In the example above, the say_hi in the
environment has been shadowed by the local variable say_hi.

defaultbl([tbl,] fn)

Sets the __index of table tbl to use the function fn to generate table
values when a missing key is looked up.

extend(arg1, arg2, [rest...])

Chains together a series of tables by their metatable’s __index property.
Overwrites the metatable of all objects except for the last with a new table
whose __index is set to the next table.

Returns the first argument.

a = { hello: "world" }
b = { okay: "sure" }

extend a, b

print a.okay

copy(tbl)

Creates a shallow copy of a table, equivalent to:

copy = (arg) -> {k,v for k,v in pairs self}

Class/Object Functions

is_object(value)

Returns true if value is an instance of a MoonScript class, false otherwise.

type(value)

If value is an instance of a MoonScript class, then return it’s class object.
Otherwise, return the result of calling Lua’s type method.

class MyClass
  nil

x = MyClass!
assert type(x) == MyClass

bind_methods(obj)

Takes an instance of an object, returns a proxy to the object whose methods can
be called without providing self as the first argument.

obj = SomeClass!

bound_obj = bind_methods obj

-- following have the same effect
obj\hello!
bound_obj.hello!

It lazily creates and stores in the proxy table the bound methods when they
are first called.

mixin(obj, class, [args...])

Copies the methods of a class cls into the table obj, then calls the
constructor of the class with the obj as the receiver.

In this example we add the functionality of First to an instance of Second
without ever instancing First.

class First
  new: (@var) =>
  show_var: => print "var is:", @var

class Second
  new: =>
    mixin self, First, "hi"

a = Second!
a\show_var!

Be weary of name collisions when mixing in other classes, names will be
overwritten.

mixin_object(obj, other_obj, method_names)

Inserts into obj methods from other_obj whose names are listed in
method_names. The inserted methods are bound methods that will run with
other_obj as the receiver.

class List 
  add: (item) => print "adding to", self
  remove: (item) => print "removing from", self

class Encapsulation
  new: =>
    @list = List!
    mixin_object self, @list, {"add", "remove"}

e = Encapsulation!
e.add "something"

mixin_table(a, b, [names])

Copies the elements of table b into table a. If names is provided, then
only those names are copied.

Misc Functions

fold(items, fn)

Calls function fn repeatedly with the accumulated value and the current value
by iterating over items. The accumulated value is the result of the last call
to fn, or, in the base case, the first value. The current value is the value
being iterated over starting with the second item.

items is a normal array table.

For example, to sum all numbers in a list:

numbers = {4,3,5,6,7,2,3}
sum = fold numbers, (a,b) -> a + b

Debug Functions

debug.upvalue(fn, key[, value])

Gets or sets the value of an upvalue for a function by name.