惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
宝玉的分享
宝玉的分享
小众软件
小众软件
有赞技术团队
有赞技术团队
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
MyScale Blog
MyScale Blog
Engineering at Meta
Engineering at Meta
Stack Overflow Blog
Stack Overflow Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
Netflix TechBlog - Medium
D
Docker
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MongoDB | Blog
MongoDB | Blog
WordPress大学
WordPress大学
J
Java Code Geeks
罗磊的独立博客
V
Visual Studio Blog
雷峰网
雷峰网
H
Help Net Security
T
The Blog of Author Tim Ferriss
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
F
Fortinet All Blogs

jdhao's digital space

Conversion between base64 and OpenCV or PIL Image 腾讯云对象存储博客图床开启 CDN 加速(不需要购买额外域名) Search and Replace in Multiple Files in Vim/Neovim Change Table Column Width in LaTeX Image or Table Side by Side in LaTeX LaTeX 并排显示图像或表格 Firenvim: Neovim inside Your Browser Content inside HTML tags missing in Latest Hugo? Creating Markdown Front Matter with Ultisnips Labelme JSON 标注格式转 voc XML 格式 Nifty Nvim Techniques That Make My Life Easier -- Series 6 macOS 下如何为视频制作字幕 Running Command Asynchronously inside Neovim Resolving Merge Conflict after Git Stash Pop Pylint: command not found? A Hands-on Experience with Neovim's Built-in LSP Support How to Convert PDF to Images with Imagemagick 互联网上常用缩略语集锦 File Backup in Neovim Converting PDF Pages to Images with Poppler Nifty Nvim Techniques That Make My Life Easier -- Series 5 Neovim Configuration for System-wide Use How to sort a list of tuple or list in Python -- lambda or itemgetter? Building A Vim Statusline from Scratch 人类第一颗原子弹爆炸始末 Distributed Training in PyTorch with Horovod Learning Expect Programming Essential Knowledge about SSH Nifty LaTeX Techniques -- Series 1 更改 Adsense 邮寄地址,重新寄送 PIN
Lua Learning Notes
2022-05-21 · via jdhao's digital space

As a long time nvim user, I am learning Lua and slowly transition my nvim config to lua. In this script, I will share some tips and lessons I have learned the hard way.

The colon operator#

In Lua code, we may see the colon operator followed by some object method. For example, if we have a string x and want to find the length of this string. In Python, we do x.len(), but this will be an error in Lua:

Error

stdin:1: bad argument #1 to 'len' (string expected, got no value)
stack traceback:
    [C]: in function 'string.len'
    stdin:1: in main chunk
    [C]: in ?

In Lua, we need to use x:len() (or you can use string.len(x) like len(x) in Python):

x = 'foo bar'
x.len()  --> this is an error
x:len()  --> works without errors

x is of type string, when we use x.len(), if it does not exist, lua will look at the metatable of x and find the __index key. The metatable of x is like this:

{
  __index = {
    byte = <function 1>,
    char = <function 2>,
    dump = <function 3>,
    find = <function 4>,
    format = <function 5>,
    gmatch = <function 6>,
    gsub = <function 7>,
    len = <function 8>,
    lower = <function 9>,
    match = <function 10>,
    rep = <function 11>,
    reverse = <function 12>,
    sub = <function 13>,
    upper = <function 14>
  }
}

It will then execute the function corresponding to key len. However, since function len() requires an argument, so we get the above error.

If we instead use x:len(), we are implicitly pass x itself as the first argument:

A call v:name(args) is syntactic sugar for v.name(v,args), except that v is evaluated only once.

So we are actually using x.len(x). In fact, if we use x.len(x), it works perfectly fine.

Ref:

The difference between defining function with colon and dot#

As discussed in the above section, when we use colon operator in Lua, we are implicitly passing the object itself (called self) to the function.

Suppose we want to implement a string function to concatenate two strings, we can use both the dot and colon operators. But the function signature will be a little different:

local x = "hello world"

function string.add1(str1, str2)
  print(string.format("str1: %s, str2: %s", str1, str2))

  return string.format("%s%s", str1, str2)
end

function string:add2(s)
  print(string.format("str1: %s, str2: %s", self, s))

  return string.format("%s%s", self, s)
end


print(x:add1("abc"))
print(x:add2("abc"))

In this example, if we use dot operator, we must explicitly provide the two parameters. For the colon operator, the first string is implicitly provided as self, which you can access in the function body. So this function has only one parameter.

If you run the code, their result will be exactly the same.

Ref:

The weirdness of Lua REPL#

If we have the following code in test.lua:

it will print out 1, not nil. Expected result, nothing special.

In the Lua REPL, if we type the following command:

the output is surprisingly nil, not 1! Crazy, isn’t it?

The reason is that in Lua REPL, each line is treated as a block. Basically, a block is an area where a variable is visible. Local variables only work in that block. For example, the following works:

This is because when lua execute a file, it treat the file as a block, so local variable x does not expire in the next line. Actually we can manually create a block in lua file with do ... end (see doc here).

It is a little weird, but that is how lua REPL works.

Ref:

In Lua, both 0 and empty string is true#

Unlike Python and other programming languages, both 0 and empty string is considered true in lua1, which is weird. In Lua, only false and nil is considered false.

if '' then
  print('empty str is true')
else
  print('empty str is false')
end

if 0 then
  print('zero is true')
else
  print('zero is false')
end

If you run the above code, you will get the following output:

empty str is true
zero is true

Lua table index starts from 1, not 0#

This feature trips me really hard and I ended up debugging my code for nearly half of an hour. So if we have a table local a = {1, 2, 3}, the first element will be a[1] not a[0].

I have repeated forgotten this and made mistakes.

Ref:

Why use parentheses around literal strings when call its method?#

If you use a literal string and want to call string method, you need to wrap the string with parentheses. This is how the Lua syntax works.

  • Right: print(("hello"):len())
  • Wrong: print("hello":len())

Ref: