lua-users home
lua-l archive

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


Le Tue, 10 Nov 2009 10:35:53 +0000,
Duncan Cross <duncan.cross@gmail.com> s'exprima ainsi:

> On Tue, Nov 10, 2009 at 8:57 AM, spir <denis.spir@free.fr> wrote:
> > Hello,
> >
> > Is there any builtin way to output table content? Couldn't find in docs,
> > maybe I'm blind... Also, I would enjoy some clues about the reasoning for
> > tostring(t) not doing that by default (and print(t) not writing that).
> > Probably getting the memory address is useful in specific occasions, so
> > there should certainly be a method for this in library "table". But the
> > table content is certainly what we need in most cases, esp. during
> > developpment/testing/debug phases, so that this should be the easiest
> > output to get. Or am I missing something
> >
> > Below a (superficially tested) example of what I mean. (The func names
> > don't pretend to be best.) Still, I guess the default output for a table
> > should be a (flat) view of its content. Even if big (the programmer knows
> > it).

Global comment: You're right, my trial is full of flaws. But this is a first trial. Anyway a standard & easy (print()) manner to output tables is highly useful I guess, even if not perfect is all cases. What do you all think?

> There is no such standard function, and I believe the main reason is
> loops - a table might (directly or indirectly) contain fields that
> refer to the table itself. For example, the global variable _G is a
> reference to the global variables table itself, so if you try to use
> your function to display _G then it will get into an infinite loop
> trying to display _G._G._G._G...

Right.

> Now, of course you can rewrite your print function to keep track of
> the hierarchy and stop itself when it detects it is about to go into
> an infinite loop. But, what do you output instead? It is not trivial
> to be concise, meaningful, unambiguous and fit for all purposes here,
> as a standard function would have to be.

Have no idea how to identify the root table itself (after, I'm a beginner -- but see also (*)) as we get the object, while nested ones can be identified while walking, sure.
As I said, the output needs not be perfect and a simple placeholder like <recursion to 'name'> would be fine for me.


Below python's solution (I don't mean python's choices are good, it's just an example):
d = {'a':1, 'b':2, 'c':3}
print d
d['b']=d
print d
==>
{'a': 1, 'c': 3, 'b': 2}
{'a': 1, 'c': 3, 'b': {...}}

> One thing you should be also be aware of is that the keys of a Lua
> table can be (almost) any value, not only a string. For example, this
> would be valid thing to do in T.test():
> 
>   local abcd = {a=1, b=2, c=3, d=4}
>   circle[abcd] = true
> 
> ...and would eventually cause an error at 'key .. T.KS', since 'key'
> would be a table not a string. Having a representation that displays
> tables-as-keys nicely is also not that easy.

Well, I could just add a tostring(), but rather not develop keys, I guess. The issue again beeing we cannot a get a key's own name (here 'abcd'), there is no obvious placeholder else maybe the type: eg write <table> or <function> when the key is neither a number nore a string.

table:
   foo: bar
   <table>: true

Wonder how lua copes with nonstable keys (for the table key can be modified, so that the hash value will change). Any way, for 'static' objects, python would do so:

def f():pass
d[f]=4
print d
==>
{'a': 1, 'c': 3, 'b': {...}, <function f at 0xb7e9f4c4>: 4}

But we cannot implement this "manually", I guess, cause there is no way to get the key's name, only the data -- unless I'm missing something obvious (see (*) again).

> -Duncan
> 

Thanks for your comments,
Denis

(*) Other languages don't let you get the _name_ of an argument neither, nore its expression in calling code, except for highly reflexive ones like Io. So that it's impossible for instance to write the developper's quick debug dream func:

show = function(obj)
   print(obj.name..': '..tostring(obj))

show(count) ==> count: 3

or even better

show = function(obj)
   print(obj.expression..': '..tostring(obj))
show(count+1) ==> count+1: 4

Sure, we can write: print("count +1: "..tostring(count)). But this is so practicle, especially in languages languages well fitted for fast testing and debugging, that I guess most of us use simple prints as main everyday debug facility, and really  wonder why such a func is not implemented in all scripting languages.
Actually, when I design & implement my own Pl, this will be the first func I write ;-)

Denis
------
la vita e estrany