table indexing

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

table indexing

Hur Butun
Dear all,

I am having an issue when indexing the table output of a function. 

I needed a physical unit conversion functionality and found the great function below on github:

I needed to make some modifications to output a table instead of string. Now after my minor modifications the function outputs a table with 'value' and 'unit' indices (see the modified function in the attachment). However I cannot index the output table with 'unit' afterwards, it always returns to nil.

I am a beginner in lua and I use it at very basic level so I am not able to understand what the problem is. 

I would appreciate if you help me to fix this issue.

Many thanks in advance.

Best,

Hur

middleclass.lua (8K) Download Attachment
MIT-LICENSE.lua (1K) Download Attachment
physvalue.lua (26K) Download Attachment
unit_conv_MIT_test.lua (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Ericson Carlos

Have not run your code, but you might want to change 'tbl = {}' to 'local tbl = {}'. As of now all variables bound to a return value of :format will refer to a single global table.

Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Hur Butun-2
Thank you for your remark.

I changed tbl to a local parameter. I still have the problem with indexing though.

--
Hür Bütün
PhD student 

École Polytechnique Fédérale de Lausanne (EPFL) 
Industrial Process and Energy Systems Engineering (IPESE) 

EPFL Valais Wallis 
SCI-STI-FM
Rue de l'Industrie 17 
Case Postale 440, CH-1951 Sion 
tel:+41 21 69 58252

2016-10-15 23:22 GMT+02:00 rexonf <[hidden email]>:

Have not run your code, but you might want to change 'tbl = {}' to 'local tbl = {}'. As of now all variables bound to a return value of :format will refer to a single global table.


Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Javier Guerra Giraldez
On 17 October 2016 at 08:49, Hur Butun <[hidden email]> wrote:
> I changed tbl to a local parameter. I still have the problem with indexing
> though.


if you could reduce your problem to a minimal example, it would be far
easier for any of us to help.  In fact, it's very common that just by
doing so you find the issue yourself.

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Jonathan Goble
In reply to this post by Hur Butun
On Fri, Oct 14, 2016 at 8:35 AM, Hur Butun <[hidden email]> wrote:
> I needed to make some modifications to output a table instead of string. Now
> after my minor modifications the function outputs a table with 'value' and
> 'unit' indices (see the modified function in the attachment). However I
> cannot index the output table with 'unit' afterwards, it always returns to
> nil.

This is what I get:

>>> p = require 'physvalue'
>>> p.u.m:format().unit
m
>>> p.u.m:format().value
1.0

Exactly what are you trying to index? In this example, if you are
trying to do `p.u.m.unit', that doesn't work because the table you
want is only produced on demand by calling the `format()` method. The
`unit` and `value` fields are not present in the object itself.

Also, note that the `__tostring()` metamethod currently delegates to
`format()`, so the result of (in this example) `print(p.u.m)` is an
error:

>>> print(p.u.m)
stdin:1: 'tostring' must return a string to 'print'
stack traceback:
        [C]: in function 'print'
        stdin:1: in main chunk
        [C]: in ?

Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Hur Butun
I am sorry, indeed I should have given an example. 

With 'new' subfunction I can define a value with physical unit and the convert it to another unit. 

So if I define an example like this:
pv=require('physvalue')
local example=pv:new('',450, 'W')
print(example.unit)

'example' is a table with 'unit' and 'value' indices if I display it using a debugger. However when I try to index 'example' with 'unit' I get nil. 

I am attaching the example if you want to test it yourself. 




2016-10-17 10:29 GMT+02:00 Jonathan Goble <[hidden email]>:
On Fri, Oct 14, 2016 at 8:35 AM, Hur Butun <[hidden email]> wrote:
> I needed to make some modifications to output a table instead of string. Now
> after my minor modifications the function outputs a table with 'value' and
> 'unit' indices (see the modified function in the attachment). However I
> cannot index the output table with 'unit' afterwards, it always returns to
> nil.

This is what I get:

>>> p = require 'physvalue'
>>> p.u.m:format().unit
m
>>> p.u.m:format().value
1.0

Exactly what are you trying to index? In this example, if you are
trying to do `p.u.m.unit', that doesn't work because the table you
want is only produced on demand by calling the `format()` method. The
`unit` and `value` fields are not present in the object itself.

Also, note that the `__tostring()` metamethod currently delegates to
`format()`, so the result of (in this example) `print(p.u.m)` is an
error:

>>> print(p.u.m)
stdin:1: 'tostring' must return a string to 'print'
stack traceback:
        [C]: in function 'print'
        stdin:1: in main chunk
        [C]: in ?



example.lua (114 bytes) Download Attachment
middleclass.lua (8K) Download Attachment
MIT-LICENSE.lua (1K) Download Attachment
physvalue.lua (26K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Hur Butun
In reply to this post by Jonathan Goble
@Jonathan,

I am trying to index the output of the function. I define parameters with unit with 'new' subfunction such as:
pv=require('physvalue')
myElec = pv:new('',450, 'W')

With this myElec is a table with 'value' and 'unit' indices. However if I try to index it such as 
myElec.unit

I get nil although in the 'unit' index of the table output of the function it is 'W'


2016-10-17 10:29 GMT+02:00 Jonathan Goble <[hidden email]>:
On Fri, Oct 14, 2016 at 8:35 AM, Hur Butun <[hidden email]> wrote:
> I needed to make some modifications to output a table instead of string. Now
> after my minor modifications the function outputs a table with 'value' and
> 'unit' indices (see the modified function in the attachment). However I
> cannot index the output table with 'unit' afterwards, it always returns to
> nil.

This is what I get:

>>> p = require 'physvalue'
>>> p.u.m:format().unit
m
>>> p.u.m:format().value
1.0

Exactly what are you trying to index? In this example, if you are
trying to do `p.u.m.unit', that doesn't work because the table you
want is only produced on demand by calling the `format()` method. The
`unit` and `value` fields are not present in the object itself.

Also, note that the `__tostring()` metamethod currently delegates to
`format()`, so the result of (in this example) `print(p.u.m)` is an
error:

>>> print(p.u.m)
stdin:1: 'tostring' must return a string to 'print'
stack traceback:
        [C]: in function 'print'
        stdin:1: in main chunk
        [C]: in ?


Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Jonathan Goble
On Mon, Oct 17, 2016 at 5:19 AM, Hur Butun <[hidden email]> wrote:

> @Jonathan,
>
> I am trying to index the output of the function. I define parameters with
> unit with 'new' subfunction such as:
> pv=require('physvalue')
> myElec = pv:new('',450, 'W')
>
> With this myElec is a table with 'value' and 'unit' indices. However if I
> try to index it such as
> myElec.unit
>
> I get nil although in the 'unit' index of the table output of the function
> it is 'W'

No, `myElec` is an instance of the `PhysValue` class. That instance
does not contain the fields you are looking for. In order to get the
table with those fields, you must call the instance's `format()`
method, which (as modified by you) returns the table with those
fields.

I think the possible source of confusion is that the original version
of the module gives PhysValue instances a __tostring metamethod that
simply delegates to format(). Therefore, I think you may have just
typed (to use your example here) `pv:new('', 450, 'W')` into the Lua
prompt, gotten the string output by format(), tracked down where that
string was generated, and changed that thinking that it would change
the return value of the pv:new() call.

But it doesn't; pv:new() still returns a PhysValue instance. When you
just type in an expression (such as the pv:new() call), Lua, in an
attempt to be helpful, automatically calls tostring() on the value of
the expression (here, the PhysValue instance returned by pv:new) to
get a "nice" output. When you assign the return value to a variable,
however, that doesn't happen, so here you need to do that explicitly
by calling the format() method.

Does that make sense? (It's 5:45 AM here and I need to get to bed, so
apologies if I'm sleepy-rambling.)

Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Hur Butun
To be honest that is exactly what happened. As I didn't write the function myself and it is advanced compared to my basic lua knowledge I tracked where the output string is created and changed the return of that function. 

Indexing example:format() works and I think I can use it instead of trying to index the output of the function directly. 

Thanks for your help and detailed explanation


2016-10-17 11:46 GMT+02:00 Jonathan Goble <[hidden email]>:
On Mon, Oct 17, 2016 at 5:19 AM, Hur Butun <[hidden email]> wrote:
> @Jonathan,
>
> I am trying to index the output of the function. I define parameters with
> unit with 'new' subfunction such as:
> pv=require('physvalue')
> myElec = pv:new('',450, 'W')
>
> With this myElec is a table with 'value' and 'unit' indices. However if I
> try to index it such as
> myElec.unit
>
> I get nil although in the 'unit' index of the table output of the function
> it is 'W'

No, `myElec` is an instance of the `PhysValue` class. That instance
does not contain the fields you are looking for. In order to get the
table with those fields, you must call the instance's `format()`
method, which (as modified by you) returns the table with those
fields.

I think the possible source of confusion is that the original version
of the module gives PhysValue instances a __tostring metamethod that
simply delegates to format(). Therefore, I think you may have just
typed (to use your example here) `pv:new('', 450, 'W')` into the Lua
prompt, gotten the string output by format(), tracked down where that
string was generated, and changed that thinking that it would change
the return value of the pv:new() call.

But it doesn't; pv:new() still returns a PhysValue instance. When you
just type in an expression (such as the pv:new() call), Lua, in an
attempt to be helpful, automatically calls tostring() on the value of
the expression (here, the PhysValue instance returned by pv:new) to
get a "nice" output. When you assign the return value to a variable,
however, that doesn't happen, so here you need to do that explicitly
by calling the format() method.

Does that make sense? (It's 5:45 AM here and I need to get to bed, so
apologies if I'm sleepy-rambling.)


Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Ericson Carlos
That PhysValue class is weird in that it does not have a 'getUnit' method. Seems easy to add:

function PhysValue:getUnit () return self.symbol end

Or maybe the user should just index 'symbol', but that's a weird name for unit.
Reply | Threaded
Open this post in threaded view
|

Re: table indexing

Hur Butun-2
I added 'gettbl' which returns to a table with value and unit indices now. 

I will check if it works this way

--
Hür Bütün
PhD student 

École Polytechnique Fédérale de Lausanne (EPFL) 
Industrial Process and Energy Systems Engineering (IPESE) 

EPFL Valais Wallis 
SCI-STI-FM
Rue de l'Industrie 17 
Case Postale 440, CH-1951 Sion 
tel:+41 21 69 58252

2016-10-17 18:21 GMT+02:00 rexonf <[hidden email]>:
That PhysValue class is weird in that it does not have a 'getUnit' method. Seems easy to add:

function PhysValue:getUnit () return self.symbol end

Or maybe the user should just index 'symbol', but that's a weird name for unit.