阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

    教程列表

    数据库
    抓包专区
    测试专区

    CoffeeScript 解释器模式

    解释器模式

    问题

    其他人需要以控制方式运行你的一部分代码。相对地,你选择的语言不能以一种简洁的方式表达问题域。

    解决方案

    使用解释器模式来创建一个你翻译为特定代码的领域特异性语言(domain-specific language)。

    我们来做个假设,例如用户希望在你的应用程序中执行数学运算。你可以让他们正向运行代码来演算指令(eval)但这会让他们运行任意代码。相反,你可以提供一个小型的“堆栈计算器(stack calculator)”语言,用来做单独分析,以便只运行数学运算,同时报告更有用的错误信息。

    class StackCalculator
        parseString: (string) ->
            @stack = [ ]
            for token in string.split /\s+/
                @parseToken token
    
            if @stack.length > 1
                throw "Not enough operators: numbers left over"
            else
                @stack[0]
    
        parseToken: (token, lastNumber) ->
            if isNaN parseFloat(token) # Assume that anything other than a number is an operator
                @parseOperator token
            else
                @stack.push parseFloat(token)
    
        parseOperator: (operator) ->
            if @stack.length < 2
                throw "Can't operate on a stack without at least 2 items"
    
            right = @stack.pop()
            left = @stack.pop()
    
            result = switch operator
                when "+" then left + right
                when "-" then left - right
                when "*" then left * right
                when "/"
                    if right is 0
                        throw "Can't divide by 0"
                    else
                        left / right
                else
                    throw "Unrecognized operator: #{operator}"
    
            @stack.push result
    
    calc = new StackCalculator
    
    calc.parseString "5 5 +" # => { result: 10 }
    
    calc.parseString "4.0 5.5 +" # => { result: 9.5 }
    
    calc.parseString "5 5 + 5 5 + *" # => { result: 100 }
    
    try
        calc.parseString "5 0 /"
    catch error
        error # => "Can't divide by 0"
    
    try
        calc.parseString "5 -"
    catch error
        error # => "Can't operate on a stack without at least 2 items"
    
    try
        calc.parseString "5 5 5 -"
    catch error
        error # => "Not enough operators: numbers left over"
    
    try
        calc.parseString "5 5 5 foo"
    catch error
        error # => "Unrecognized operator: foo"
    

    讨论

    作为一种替代编写我们自己的解释器的选择,你可以将现有的 CoffeeScript 解释器与更自然的(更容易理解的)表达自己的算法的正常方式相结合。

    class Sandwich
        constructor: (@customer, @bread='white', @toppings=[], @toasted=false)->
    
    white = (sw) ->
        sw.bread = 'white'
        sw
    
    wheat = (sw) ->
        sw.bread = 'wheat'
        sw
    
    turkey = (sw) ->
        sw.toppings.push 'turkey'
        sw
    
    ham = (sw) ->
        sw.toppings.push 'ham'
        sw
    
    swiss = (sw) ->
        sw.toppings.push 'swiss'
        sw
    
    mayo = (sw) ->
        sw.toppings.push 'mayo'
        sw
    
    toasted = (sw) ->
        sw.toasted = true
        sw
    
    sandwich = (customer) ->
        new Sandwich customer
    
    to = (customer) ->
        customer
    
    send = (sw) ->
        toastedState = sw.toasted and 'a toasted' or 'an untoasted'
    
        toppingState = ''
        if sw.toppings.length > 0
            if sw.toppings.length > 1
                toppingState = " with #{sw.toppings[0..sw.toppings.length-2].join ', '} and #{sw.toppings[sw.toppings.length-1]}"
            else
                toppingState = " with #{sw.toppings[0]}"
        "#{sw.customer} requested #{toastedState}, #{sw.bread} bread sandwich#{toppingState}"
    
    send sandwich to 'Charlie' # => "Charlie requested an untoasted, white bread sandwich"
    send turkey sandwich to 'Judy' # => "Judy requested an untoasted, white bread sandwich with turkey"
    send toasted ham turkey sandwich to 'Rachel' # => "Rachel requested a toasted, white bread sandwich with turkey and ham"
    send toasted turkey ham swiss sandwich to 'Matt' # => "Matt requested a toasted, white bread sandwich with swiss, ham and turkey"
    

    这个实例可以允许功能层实现返回修改后的对象,从而外函数可以依次修改它。示例通过借用动词和介词的用法,把自然语法提供给结构,当被正确使用时,会像自然语句一样结束。这样,利用 CoffeeScript 语言技能和你现有的语言技能可以帮助你关于捕捉代码的问题。

    卖前端学习教程

    只需几十元,就能买到培训班的内部教程!开启高薪之路!

    零基础小白阿里P7的教程都有!

    同时长期收购所有培训班的前端教程

    目录
    目录