Re: __tostring does not work with complex

  • From: Laurent Deniau <Laurent.Deniau@xxxxxxx>
  • To: "<luajit@xxxxxxxxxxxxx>" <luajit@xxxxxxxxxxxxx>
  • Date: Thu, 23 Jul 2015 13:03:51 +0000

On Jul 23, 2015, at 2:19 PM, Laurent Deniau
<laurent.deniau@xxxxxxx<mailto:laurent.deniau@xxxxxxx>> wrote:

On Jul 23, 2015, at 1:29 PM, Simon Schick
<demwizzy@xxxxxxxxx<mailto:demwizzy@xxxxxxxxx>> wrote:

Hey,

I'm not entirely sure but maybe
this<http://luajit.org/ext_ffi_api.html#ffi_metatype> applies here?

"Note that pre-defined operations on types have precedence..."

As a workaround you can get the complex metatable via debug.getmetatable and
set your custom tostring function there:

debug.getmetatable(3i).__tostring = function(x) return "something" end
=tostring(3i)
something


you are right, but in principle the metatable should not be modified once set
with ffi.metatype, isn't it?
and the code below works fine for all other cdata… Is complex a special case?

I spoke too quickly, as expected, setting __tostring after the call to metatype
breaks the existing metatable and istype('complex', x) inside __tostring return
false. It works in the small code sample because there is no previous metatable
set (I guess). For example, once metatype is called, the setup with debug
changes the type and the fields .re and .im do not exist anymore.

Best,
Laurent.



On 23 July 2015 at 12:29, Laurent Deniau
<Laurent.Deniau@xxxxxxx<mailto:Laurent.Deniau@xxxxxxx>> wrote:
Hi,

Here is a small example that does not work as expected (?) where numtostring is
never called and It works with other data.

Best,
Laurent.


local ffi = require 'ffi'

local M = {}

M.format = "%- 10.4f"

local function numtostring (x)
io.write('numtostring called with ', x,'\n')
return string.format(M.format, x)
end

function M.__tostring (x)
if x.im<http://x.im/> == 0 then return
numtostring(x.re<http://x.re/>)
elseif x.re<http://x.re/> == 0 then return string.format('%si',
numtostring(x.im<http://x.im/>))
elseif x.im<http://x.im/> < 0 then return string.format('%s%si',
numtostring(x.re<http://x.re/>),numtostring(x.im<http://x.im/>))
else return
string.format('%s+%si',numtostring(x.re<http://x.re/>),numtostring(x.im<http://x.im/>))
end
end

ffi.metatype('complex', M)

print(3i)
io.write(tostring(3i),'\n')


--
Laurent Deniau http://cern.ch/mad
Accelerators Beam Physics mad@xxxxxxx<mailto:mad@xxxxxxx>
CERN, CH-1211 Geneva 23 Tel: +41 (0) 22 767
4647<tel:%2B41%20%280%29%2022%20767%204647>




Other related posts: