Lua DSL 还是巧妙的闭包?
我正在尝试使用 Lua 并尝试实现一些列表处理逻辑。我不确定我是否真正掌握了协程和匿名函数的力量,但我正在尝试。我知道这些东西在其他脚本语言(如 Ruby/Groovy/Javascript)中是如何工作的,并且我想在 Lua 中做一些同样聪明的事情。这是我想出的例子:
model = { { player = "Cliff", age = 35, gender = "male" }, { player = "Ally", age = 36, gender = "female" }, { player = "Jasmine", age = 13, gender = "female" }, { player = "Lauren", age = 6.5, gender = "female" } }
function allplayers()
return coroutine.create(function()
for idx, each in ipairs(model) do
coroutine.yield(idx, each)
end
end)
end
function handlePlayers(source)
local status, idx, each = coroutine.resume(source)
while each do
print(idx, each.player)
status, idx, each = coroutine.resume(source)
end
end
function having(source, predicate)
return coroutine.create(function()
local status, idx, each = coroutine.resume(source)
while each do
if predicate(each) then
coroutine.yield(idx, each)
end
status, idx, each = coroutine.resume(source)
end
end)
end
handlePlayers(having(allplayers(), function(each) return each.age < 30 end))
理想情况下,我希望能够编写如下代码:
allplayers(having(function(each) return each.age < 30 end))
甚至更好:
allplayers(having({each.age < 30 }))
产生相同的输出,但我不太清楚如何或即使这可以完成吧。我上面的内容对于所有迭代和循环等等来说似乎太多余了。有没有更绝妙的方法来做到这一点? (天哪,我怀念用 Groovy 编码,因为总有一种更绝妙的方式来做某事......)
I'm cutting my teeth with Lua and trying to implement some list processing logic. I'm not sure if I truly grasp the power of coroutines and anonymous functions but I'm trying. I know how these things work in other scripting languages like Ruby/Groovy/Javascript and I'm wanting to do something equally as clever in Lua. Here's what I've come up with as an example:
model = { { player = "Cliff", age = 35, gender = "male" }, { player = "Ally", age = 36, gender = "female" }, { player = "Jasmine", age = 13, gender = "female" }, { player = "Lauren", age = 6.5, gender = "female" } }
function allplayers()
return coroutine.create(function()
for idx, each in ipairs(model) do
coroutine.yield(idx, each)
end
end)
end
function handlePlayers(source)
local status, idx, each = coroutine.resume(source)
while each do
print(idx, each.player)
status, idx, each = coroutine.resume(source)
end
end
function having(source, predicate)
return coroutine.create(function()
local status, idx, each = coroutine.resume(source)
while each do
if predicate(each) then
coroutine.yield(idx, each)
end
status, idx, each = coroutine.resume(source)
end
end)
end
handlePlayers(having(allplayers(), function(each) return each.age < 30 end))
Ideally I'd like to be able to write code like:
allplayers(having(function(each) return each.age < 30 end))
or even better:
allplayers(having({each.age < 30 }))
to produce the same output but I can't quite get my head around how or even if this can be done. What I have above seems way too redundant with all the iteration and loops and all. Is there a groovier way to do this? (Boy I miss coding in Groovy, because there was always a groovier way to do something...)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果不需要重用过滤后的结果,请考虑迭代器:
If you don't need to reuse the filtered result, consider an iterator:
这是极其复杂和过度设计的。您想通过谓词过滤一个列表。那么就这样做吧;这是一个简单的循环。就写吧。
即使您绝对必须以函数式风格执行此操作(Lua 不是函数式语言。它可以以这种方式工作,但它不是函数式的),协程也不合适。
观察:
看到了吗?根本不需要协程。
This is incredibly overcomplicated and overdesigned. You want to filter one list via a predicate. So do that; it's a simple loop. Just write it.
Even if you absolutely must do this in a functional style (Lua is not a functional language. It can work that way, but it's not functional), coroutines aren't appropriate.
Observe:
See? No need for coroutines at all.
您可能想尝试模仿 Underscore.js JavaScript 库。
您的示例如下所示:
请注意,Lua 不会为您提供任何其他语法糖(除了
:
运算符)。如果您确实想要更短的语法,您应该查看 Metalua,它允许您更改语言,并提供以下开箱即用的短函数语法:You may want to try Underscore.lua modeled after the Underscore.js JavaScript library.
Your example would look like this:
Note that Lua won't give you any other syntax sugar (apart from the
:
operator). If you really want shorter syntax, you should look at Metalua, which allows you to change the language, and provides the following short function syntax out-of-the-box: