lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

So why ('A'):byte(2) returns nothing (empty list) instead of nil ?
How does type() differentiate if we pass it an empty list (we get an error) or nil (we get 'nil')?
Is it just a bug of type() ???

Can you test this and confirm that
- the public id (or nil) is always passed to func, and
- the public info is never passed to func, but replaced by the private id?

function getpublic_none(id) end
function getpublic_id(id) return id end
function getpublic_id_nil(id) return id,nil end
function getpublic_id_info(id) return id,'public' end
function getprivate_id_info(id) return id,'private' end
function func(id, info, id2, info2) print(id, publicinfo, '/', id2, info2) end
local id=123
func(userid, getpublic_none(id), getprivate_id_info(id))
func(userid, getpublic_id(id), getprivate_id_info(id))
func(userid, getpublic_id_nil(id), getprivate_id_info(id))
func(userid, getpublic_id_info(id), getprivate_id_info(id))

i.e., within comma-separated list of expressions, can you confirm that the "comma operator" applies a "strict" rule to the first operand and reduces it to a single value (or nil) while still allowing the second operand to be a list of variable length, so that only the last given _expression_ in the list of expressions may have variable length (for arguments list, or for table constructors, or for values given to an assignment statement) ?

In that case, wouldn't it be simpler to just append a trailing final comma to any _expression_ list so that even id that last _expression_ does not return any value or returns multiple one,s it will be downcasted to a single value or nil ? I mean, it's just simpler to write
   e1, e2, e3,
instead of:
   e1, e2, (3)
which looks like a trick with this extra pair or parentheses around the last _expression_ !

Note that table constructors, I always use the trailing comma, which should also be valid for arguments lists of function calls:

  type(('A'):byte(2)) --> an error is thrown
  type((('A'):byte(2))) --> no error thrown, returns the string 'nil'... but tricky
  type(('A'):byte(2),) --> no error thrown, cleaner without the extra parentheses !
Within table constructors, we could use a "relaxed comma" (which could be noted by a pair of commas below) to append several lists or append values to a list without reducing the first list to a single value:

  { generate_a_list(),, generate_a_list() }
  { ...,, 'value' }

Le mar. 7 sept. 2021 à 06:19, Paul K <> a écrit :
> Say you have defined: function func(userid, publicdata, privatedata).
> And you call: func(userid, getpublicdata(userid), getprivatedata(userid))
> There is NO warranty at all that fun() will process publicdata containing ONLY the return value(s) of getpublicdata().
> It could happen that publicdata used by fun() will return what was returned by getprivatedata(), and that privatedata would be nil in that case.
> This would happen if getpublicdata() for example checks if userid is declared visible in some database, and if not (concealed user), it would return nothing (assuming it is equivalent to returning nil). But that userid would still have privatedata, that would suddenly be made accessible inside fun() as if it was public.

I don't think this is the case, as the second parameter will always be
`nil` if the function returns `nil` or doesn't return anything. Here
is my test:

function getpublicdata() end
function getprivatedata() return "private" end
function func(...) print(...) end
func(123, getpublicdata(userid), getprivatedata(userid))

This prints: "123 nil private" for me in Lua 5.1-5.4

> So instead of calling:  func(userid, getpublicdata(userid), getprivatedata(userid))
> You need to call:  func(userid, (getpublicdata(userid)), (getprivatedata(userid)))

No, this only makes a difference for the last parameter, so you can do
it for the last call to avoid sending *more* parameters than necessary
(for example, when string.gsub is used, but you only need the first
value returned). You *may* need it for the last parameter if you want
to guarantee that the function will see 3 parameters instead of 2
(when `getprivatedata()` doesn't return anything), but if you assign
those values to local variables, you won't see any difference.