Skip to content

Dynamically calling methods #80

@exists-forall

Description

@exists-forall

In both Lua and Moonscript, the only way to call a method with an implicit self parameter is for the name of the method to be known at compile time, like obj\method .... If you want to call a method with a dynamically determined name, you no longer have syntactic sugar to hide the rather redundant self parameter. For example:

love.keypressed = (k)->
  key_handler_obj["#{k}_pressed"] key_handler_obj

which is pretty ugly IMHO, and can lead to subtle bugs if you forget to add the second self.

I propose Moonscript implement a obj\[metname] syntax to handle such cases. With this new syntax, our code could become

love.keypressed = (k)->
  key_handler_obj\["#{k}_pressed"]!

for simple cases where the receiver is just a variable,

obj\[dyn_metname] args...

could compile to

obj[dyn_metname](obj, args...)

for more complicated cases where the method call is not being used as an expression you could use a do block to prevent extra evaluations:

love.keypressed = (k)->
  get_key_handler!\["#{k}_pressed"]!

should become

love.keypressed = function(k)
  do
    local _dynam_0 = get_key_handler()
    return _dynam_0[tostring(k) .. "_pressed"](_dynam_0)
  end
end

When there is an assignment statement and the receiver is not a simple variable, you can slightly modify the compiled code

love.keypressed = (k)->
  result = get_key_handler!\["#{k}_pressed"]!

should compile to

love.keypressed = function(k)
  local result
  do
    local _dynam_0 = get_key_handler()
    result = dynam_0[tostring(k) .. "_pressed"](_dynam_0)
  end
end

when all else fails, I.E. it's used directly within an expression and the receiver is not a simple variable, use the elegant but less efficient route of creating an anonymous function

love.keypressed = (k)->
  print get_key_handler!\["#{k}_pressed"]!

should become

love.keypressed = function(k)
  return print((function()
    local _dynam_0 = get_key_handler()
    return _dyam_0[tostring(k) .. "_pressed"](_dynam_0)
  end)())
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions