课程表

CoffeeScript 语法

CoffeeScript 类和对象

CoffeeScript 字符串

CoffeeScript 数组

CoffeeScript 日期和时间

CoffeeScript 数学

CoffeeScript 方法

CoffeeScript 元编程

CoffeeScript jQuery

CoffeeScript 正则表达式

CoffeeScript 网络

CoffeeScript 设计模式

CoffeeScript 数据库

CoffeeScript 测试

工具箱
速查手册

CoffeeScript 解释器模式

当前位置:免费教程 » JS/JS库/框架 » CoffeeScript

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

解决方案

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

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

  1. class StackCalculator
  2. parseString: (string) ->
  3. @stack = [ ]
  4. for token in string.split /\s+/
  5. @parseToken token
  6. if @stack.length > 1
  7. throw "Not enough operators: numbers left over"
  8. else
  9. @stack[0]
  10. parseToken: (token, lastNumber) ->
  11. if isNaN parseFloat(token) # Assume that anything other than a number is an operator
  12. @parseOperator token
  13. else
  14. @stack.push parseFloat(token)
  15. parseOperator: (operator) ->
  16. if @stack.length < 2
  17. throw "Can't operate on a stack without at least 2 items"
  18. right = @stack.pop()
  19. left = @stack.pop()
  20. result = switch operator
  21. when "+" then left + right
  22. when "-" then left - right
  23. when "*" then left * right
  24. when "/"
  25. if right is 0
  26. throw "Can't divide by 0"
  27. else
  28. left / right
  29. else
  30. throw "Unrecognized operator: #{operator}"
  31. @stack.push result
  32. calc = new StackCalculator
  33. calc.parseString "5 5 +" # => { result: 10 }
  34. calc.parseString "4.0 5.5 +" # => { result: 9.5 }
  35. calc.parseString "5 5 + 5 5 + *" # => { result: 100 }
  36. try
  37. calc.parseString "5 0 /"
  38. catch error
  39. error # => "Can't divide by 0"
  40. try
  41. calc.parseString "5 -"
  42. catch error
  43. error # => "Can't operate on a stack without at least 2 items"
  44. try
  45. calc.parseString "5 5 5 -"
  46. catch error
  47. error # => "Not enough operators: numbers left over"
  48. try
  49. calc.parseString "5 5 5 foo"
  50. catch error
  51. error # => "Unrecognized operator: foo"

讨论

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

  1. class Sandwich
  2. constructor: (@customer, @bread='white', @toppings=[], @toasted=false)->
  3. white = (sw) ->
  4. sw.bread = 'white'
  5. sw
  6. wheat = (sw) ->
  7. sw.bread = 'wheat'
  8. sw
  9. turkey = (sw) ->
  10. sw.toppings.push 'turkey'
  11. sw
  12. ham = (sw) ->
  13. sw.toppings.push 'ham'
  14. sw
  15. swiss = (sw) ->
  16. sw.toppings.push 'swiss'
  17. sw
  18. mayo = (sw) ->
  19. sw.toppings.push 'mayo'
  20. sw
  21. toasted = (sw) ->
  22. sw.toasted = true
  23. sw
  24. sandwich = (customer) ->
  25. new Sandwich customer
  26. to = (customer) ->
  27. customer
  28. send = (sw) ->
  29. toastedState = sw.toasted and 'a toasted' or 'an untoasted'
  30. toppingState = ''
  31. if sw.toppings.length > 0
  32. if sw.toppings.length > 1
  33. toppingState = " with #{sw.toppings[0..sw.toppings.length-2].join ', '} and #{sw.toppings[sw.toppings.length-1]}"
  34. else
  35. toppingState = " with #{sw.toppings[0]}"
  36. "#{sw.customer} requested #{toastedState}, #{sw.bread} bread sandwich#{toppingState}"
  37. send sandwich to 'Charlie' # => "Charlie requested an untoasted, white bread sandwich"
  38. send turkey sandwich to 'Judy' # => "Judy requested an untoasted, white bread sandwich with turkey"
  39. send toasted ham turkey sandwich to 'Rachel' # => "Rachel requested a toasted, white bread sandwich with turkey and ham"
  40. send toasted turkey ham swiss sandwich to 'Matt' # => "Matt requested a toasted, white bread sandwich with swiss, ham and turkey"

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

转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号