This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Nex4rius's profile picture

call copy function from within a program

Started by Nex4rius, 17 July 2017 - 04:20 PM
Nex4rius #1
Posted 17 July 2017 - 06:20 PM
In OpenComputers you could do
local copy = loadfile("/bin/cp.lua")
copy("1", "2")
and it would copy the file but in ComputerCraft when I try
local copy = loadfile("/rom/programs/copy")
copy("1", "2")

I'm getting an error.


What am I doing wrong?
Bomb Bloke #2
Posted 18 July 2017 - 12:45 AM
You're trying to call a function that doesn't exist. Try fs.copy() instead.
KingofGamesYami #3
Posted 18 July 2017 - 02:14 AM
Note that loadfile does exist, and does work. You're simply not pointing to the correct file (which would be shell.resolveProgram( "copy" )). It's much better practice to call fs.copy directly though, and there are some environment issues associated with loadfile (shell would be nil).
Bomb Bloke #4
Posted 18 July 2017 - 04:31 AM
Gah, I skimmed.

Truth be told he is pointing to the "correct" file, it's just the shell table missing from the environment that leads to the error.

Still: use fs.copy().
Nex4rius #5
Posted 18 July 2017 - 12:56 PM
Thanks :)/>

But why is the shell table missing?
Bomb Bloke #6
Posted 18 July 2017 - 02:13 PM
A ComputerCraft computer loads a number of APIs on boot, each of which is basically a collection of functions (eg "copy") shoved into a table (eg "fs") which then goes into _G. Most code can access _G and hence see those APIs.

However, the global environment table our scripts use is not _G. Rather, the tables are unique ones generated by the CraftOS shell, through which we can access _G's contents (via metatable magic), but not so readily fill _G with our globals. I assume this system is intended to stop newbies who know nothing about environments / scope from making too much of a hash of things.

Because a system can run multiple shell instances at the same time, and each of those instances will have their own idea about such things as where the current working directory might be, the shell "API" isn't placed within _G - rather, each shell instance dumps its function table into its own unique environment.

loadfile doesn't use that environment unless you specifically tell it to, so: no shell table for your loaded function. You could getfenv the current environment and pass as a second argument to loadfile, though, if you really wanted to.

(I suspect there'll be a bit of that happening once 1.80 hits - as of that build, not only does each shell instance have its own environment table, but so does every script you start via shell.run().)
Nex4rius #7
Posted 18 July 2017 - 03:25 PM
Thanks for the explanation.
I don't need multiple shell instances. My program is seperated into multiple files and I'm too lazy to change all loadfiles with getfenv so I'm taking the "easy" way and just include
_G.shell = shell
at the start.