user977828
user977828

Reputation: 7679

calculating string length causes confustion

I am confused by the following output:

local a = "string"
print(a.len)        -- function: 0xc8a8f0
print(a.len(a))     -- 6
print(len(a)) 
--[[
/home/pi/test/wxlua/wxLua/ZeroBraneStudio/bin/linux/armhf/lua: /home/pi/Desktop/untitled.lua:4: attempt to call global 'len' (a nil value)
stack traceback:
    /home/pi/Desktop/untitled.lua:4: in main chunk
    [C]: ?
]]

What is the proper way to calculate a string length in Lua?

Thank you in advance,

Upvotes: 9

Views: 9678

Answers (2)

Piglet
Piglet

Reputation: 28950

print(a.len) -- function: 0xc8a8f0

This prints a string representation of a.len which is a function value. All strings share a common metatable.

From Lua 5.4 Reference Manual: 6.4 String Manipulation:

The string library provides all its functions inside the table string. It also sets a metatable for strings where the __index field points to the string table. Therefore, you can use the string functions in object-oriented style. For instance, string.byte(s,i) can be written as s:byte(i).

So given that a is a string value, a.len actually refers to string.len

For the same reason

print(a.len(a))

is equivalent to print(string.len(a)) or print(a:len()). This time you called the function with argument a instead of printing its string representation so you print its return value which is the length of string a.

print(len(a))

on the other hand causes an error because you attempt to call a global nil value. len does not exist in your script. It has never been defined and is hence nil. Calling nil values doesn't make sense so Lua raises an error.

According to Lua 5.4 Reference Manual: 3.4.7 Length Operator

The length of a string is its number of bytes. (That is the usual meaning of string length when each character is one byte.)

You can also call print(#a) to print a's length.

The length operator was introduced in Lua 5.1,

Upvotes: 4

Robert
Robert

Reputation: 2812

You can use:

a = "string"
string.len(a)

Or:

a = "string"
a:len()

Or:

a = "string"
#a

EDIT: your original code is not idiomatic but is also working

> a = "string"
> a.len
function: 0000000065ba16e0
> a.len(a)
6

The string a is linked to a table (named metatable) containing all the methods, including len.

A method is just a function, taking the string as the first parameter.

function a.len (string) .... end

You can call this function, a.len("test") just like a normal function. Lua has a special syntax to make it easier to write. You can use this special syntax and write a:len(), it will be equivalent to a.len(a).

Upvotes: 9

Related Questions