How print all the global names used inside a tool?


(Raul (ulneiz)) #1

This is possible?The objective is to create a list that contains all the global names used.


(danoise) #2

From somewhere in your tool, issue this statement

rprint(_G)

This will print everything available to that tool - you will have to figure out what is “yours” and not.


(Raul (ulneiz)) #3

From somewhere in your tool, issue this statement

rprint(_G)

This will print everything available to that tool - you will have to figure out what is “yours” and not.

Thanks! :slight_smile: I usually use prefixes in my global names, which will come great for this. Is there any way to print all the “id” of the objects?Are these ids global in some way?


(danoise) #4

Is there any way to print all the “id” of the objects?Are these ids global in some way?

You mean viewbuilder ids? I don’t think so, they’re internal to the viewbuilder.

But I think I know what you mean - it’s necessary to have some kind of naming convention to avoid conflicts.


(Ledger) #5

You mean viewbuilder ids? I don’t think so, they’re internal to the viewbuilder.
But I think I know what you mean - it’s necessary to have some kind of naming convention to avoid conflicts.

rprint(vb.views)

seems to work, where vb = viewbuilder object

gives something like this, with ids in brackets:

[S button one] => userdata: 0x000000001DED9558 (Button object)
[S button two] => userdata: 0x000000001DED1E58 (Button object)
[dev a external ed button] => userdata: 0x000000001DED40E8 (Button object)
[dev b external ed button] => userdata: 0x000000001DEE9FC8 (Button object)
[device a button] => userdata: 0x000000001DEDB938 (Button object)
[device a popup] => userdata: 0x000000001DEEB7D8 (Popup object)
[device b button] => userdata: 0x000000001DEE0EF8 (Button object)
[device b popup] => userdata: 0x000000001DEE0018 (Popup object)
[sel + 1] => userdata: 0x000000001DEDB698 (Button object)

(danoise) #6

I stand corrected :slight_smile:


(Ledger) #7

I stand corrected :slight_smile:

and I stand educated, as never tried that before! :slight_smile:

will probably be using it though as quite handy, so thanks to Raul for the OP!


(joule) #8

This will print everything available to that tool - you will have to figure out what is “yours” and not.

Here’s a snippet that should list whatever has been added to the global environment (as per Renoise 3.1.1)

local native_environment = {
string = true, xpcall = true, package = true, tostring = true, print = true, rprint = true, _STRICT = true, os = true, unpack = true, require = true, getfenv = true, setmetatable = true, next = true, assert = true, tonumber = true, io = true, rawequal = true, collectgarbage = true, getmetatable = true, global = true, module = true, renoise = true, oprint = true, class = true, debug = true, rawset = true, bit = true, table = true, super = true, remdebug = true, ripairs = true, math = true, property = true, pcall = true, objinfo = true, newproxy = true, type = true, coroutine = true, _G = true, select = true, gcinfo = true, pairs = true, rawget = true, loadstring = true, ipairs = true, _VERSION = true, dofile = true, setfenv = true, load = true, error = true, loadfile = true }

local function list_globals()
  local list = { }
  for k, v in pairs(_G) do
    if not native_environment[k] then
      list[k] = v
    end
  end
  rprint(list)
end

list_globals()

(Ledger) #9

Here’s a snippet that should list whatever has been added to the global environment (as per Renoise 3.1.1)

Very neat, nice work!


(Ledger) #10

Just for the thread and my own learning. After a bit of reverse engineering of joules snippet:

the string key entries to populate:

local native_environment {xpcall = true ,...etc} --alternative table constructor syntax would be: local native_environment {["xpcall"] = true, ...etc}

can be found by printing all the “first level” table entries for the global table: _G (printed from a testpad, not a tool that has added any extra entries to _G)

for k, v in pairs(_G) do
 print(k)
end

These permanent entries for _G are then stripped out and the remains (tool added entries) added to list {} for printing. (printed from inside a tool that has added entries to _G)

local list = { }
for k, v in pairs(_G) do
  if not native_environment[k] then
    list[k] = v
  end
end

rprint(list)

(joule) #11

Here is another example, just to show a more intricate syntax that could be educational :slight_smile:

-- custom iterator, used on _G for finding non-native keys

local function newpairs(env_table)

 local native_environment = {
 string = true, xpcall = true, package = true, tostring = true, print = true, rprint = true, _STRICT = true, os = true, unpack = true, require = true, getfenv = true, setmetatable = true, next = true, assert = true, tonumber = true, io = true, rawequal = true, collectgarbage = true, getmetatable = true, global = true, module = true, renoise = true, oprint = true, class = true, debug = true, rawset = true, bit = true, table = true, super = true, remdebug = true, ripairs = true, math = true, property = true, pcall = true, objinfo = true, newproxy = true, type = true, coroutine = true, _G = true, select = true, gcinfo = true, pairs = true, rawget = true, loadstring = true, ipairs = true, _VERSION = true, dofile = true, setfenv = true, load = true, error = true, loadfile = true
 }

 -- make a table of all non-native keys found 
 local list = { }
 for k, v in pairs(env_table) do
 if not native_environment[k] then
 list[k] = v
 end
 end

 -- return iterator function
 local k, v 
 return function()
 k, v = next(list, k)
 if v then
 return k,v
 end
 end 

end

-- try the iterator
for k, v in newpairs(_G) do
 print(k)
end

Custom iterators are cool, so I felt compelled showing an example :slight_smile: A more practical custom iterator would be a note iterator … that would be very handy under the right circumstance. Idea:

-- note iterator, returning a custom note object
for note in allnotes(patterntrack) do
 local length = note.length
 local button = note.roll_button
end

(Ledger) #12

next() is now in my Lua vocabulary!

Apparently not as efficient as numerical iteration though:

https://medium.com/@RBX_Crazyman32/don-t-use-next-instead-of-pairs-6758bb19de61

I got roughly 3.6 seconds for the next() and pairs examples vs 1.6 seconds with the numerical for loops.

I think this came up on the forum somewhere before, but is there any other advantage other than syntax for these iterators?


(joule) #13

I got roughly 3.6 seconds for the next() and pairs examples vs 1.6 seconds with the numerical for loops.

I think this came up on the forum somewhere before, but is there any other advantage other than syntax for these iterators?

I think next and pairs are the same (pairs is using next afaik). When it comes to indexed tables, a i=i+1 iterator (ipairs) is faster indeed.

No there shouldn’t be any other difference than syntax. But that’s a big one IMO, and has a big potential for making code more clear in some circumstances. renoise.song().pattern_iterator is an iterator just like this.

Here’s another example of a custom iterator that’s similar to ipairs() but accepts “holes” in the indexes. It can be practical for something like iterating note intervals, or perhaps iterating a table that only non-empty patternlines have been copied to:

-- like ipairs, but accepting 'holes'

function cpairs(tbl)

 local index = { }
 for k, v in pairs(tbl) do
 if not (type(k) == "number") then
 return function()
 return nil
 end
 else
 index[#index+1] = k
 end
 end

 table.sort(index, function(a, b) return a < b end)

 local i = 0
 local n = #index
 return function ()
 i = i + 1
 if i <= n then return index[i], tbl[index[i]] end
 end

end

local test = { [2] = 3, [7] = 10, [4] = 2, [1000] = "yello", [0] = "hmm", [-100] = true }

for k, v in cpairs(test) do
 print(k)
end

EDIT:

Here is another small example of an iterator, also showing how to ‘extend’ the renoise.Song class. (It would actually be a good idea to refactor and overwrite the native pattern_iterator in a similar way, making it faster than the current one. Then we could start using that as the ‘standard’ method)

Click to view contents
function renoise.Song.sequence_iterator()
  local sequence = renoise.song().sequencer.pattern_sequence
  local i = 0
  local n = #sequence
  return function ()
           i = i + 1
           if i <= n then
             return i, sequence[i], renoise.song():pattern(sequence[i])
           end
         end
end
-- trying it
for seq_index, pattern_index, pattern in renoise.song().sequence_iterator() do
  print(pattern_index)
end