I'm having some trouble using relative file paths in Lua, I'm not sure what the syntax is supposed to be.
If I have something like:
Parent Directory: File1.lua
|
|-----> Folder1: script.lua
If I wanted to use script.lua in File.Lua how would I format the dofiles(), require ' ', and filename strings?
dofile and filename strings can use "Folder1/script.lua".
For require, use require"Folder1.script".
Related
So i've been trying to figure this out, im doing the following
main.lua:
package.path = io.popen("cd"):read'*all' -- to set the path the same as main.lua (for exporting)
local u = require("utilities") -- this is the line that dosent work
utilities.lua:
local u = {}
function u.GetService(s)
return require(tostring(s))
end
function u.Wait(s)
local ntime = os.clock() + s/10
repeat until os.clock() > ntime
end
function u.NPWait(s)
local ntime = os.time() + s
repeat until os.time() > ntime
end
return u
The error:
module 'utilities' not found:
Then here goes a search that DOES look in the correct folder, however it looks for .dll files
Require has never been something I've been good at, Sometimes I get it to work, sometimes it breaks like this, if someone can help me understand how to fix this then thank you, as this has been annoying me every so often
You're misunderstanding package.path.
Unlike the PATH variable used by windows and linux, in Lua you don't just tell it what directory to look in but also what the files should look like.
What you're doing is erasing the default search paths completely and replacing it with a broken path that won't find any files.
Generally speaking, to add a new directory to your path, you should add both C:\path\to\your\files\?.lua, and C:\path\to\your\files\?\init.lua, which are the two ways Lua loads modules by default.
You also shouldn't replace package.path, because you're keeping modules from being loaded elsewhere.
Your code should look somewhat like this:
local cd = io.popen("cd")
package.path = cd:read('*line') .. "\\?.lua;" .. package.path
cd:close()
The reason why it's still looking for DLL files is that package.cpath is separate, so you're not changing that.
require("utilities.lua") should work.
You have to specify how to get from the required name to the file. For example by adding a path and a file extension to it.
If you want to require c:\folder\script.lua with require("script") your package.path must contain something like c:\folder\?.lua where ? is replaced by the required name.
If you have your module in a folder with its name and let's say a init.lua for that module the path is c:\folder\?\init.lua
Just print the original package.path and see what's inside befor you overwrite it.
Refer to Lua Reference Manual 6.3 Modules: package.searchpath
A path is a string containing a sequence of templates separated by
semicolons. For each template, the function replaces each
interrogation mark (if any) in the template with a copy of name
wherein all occurrences of sep (a dot, by default) were replaced by
rep (the system's directory separator, by default), and then tries to
open the resulting file name.
For instance, if the path is the string
"./?.lua;./?.lc;/usr/local/?/init.lua" the search for the name foo.a will try to open the files ./foo/a.lua, ./foo/a.lc, and
/usr/local/foo/a/init.lua, in that order.
So in lua, i want to import a module.
I want to have my "polygon" lib in a subfolder, so i reference it like this
local polygon = require('polygon.polygon')
however, it needs another module called 'delaunay', it cannot find it as it checks the main folder
Is there anyway short of editing my library, to get this to work? (some kind of ability to add search paths?)
Thanks
To know where to look for modules, Lua's require uses the variables package.path (.lua) and package.cpath (.so/.dll). You can change them in your program to look in the directory you have it in. For consistency's sake, you can look at their contents to know which OS-specific separator to use. For example:
local sep = package.path:find("\\") and "\\" or "/"
package.path = package.path .. ";." .. sep .. "polygon" .. sep .. "?.lua"
This would include ./polygon/?.lua into the search path, and a call to require "delaunay" would therefore have the require function look for ./polygon/delaunay.lua in addition to existing paths. Bear in mind that in require strings, . denotes a separator as far as file searching is concerned, so calling require "polygon.delaunay" in this scenario will mean searching for ./polygon/polygon/delaunay.lua.
From what I understand of your question, changing the package.path variable to include the path to where your delaunay library is stored would solve your issue, although to give a specific solution more information about your project and directory structure is required.
All what loaded into package.loaded can be load with require() because require() looks first in package.loaded...
-- Lua 5.3 ( lua -i )
> package.loaded.code=load(code.dump)()
> test=require('code')
> test
function: 0x565cb820
So you can use load() or loadfile('/path/to/your_code.lua') to do this. Another nice feature of this method is to load dumped code...
> package.loaded.shell=loadfile('shell.bin')
> shell=require('shell')
> shell('cat shell.bin')
uaS�
�
xV(w#F#�d�#��F�#G���d#��F�#G���d#&�typestringoexecute
/bin/bash>
In any way, it appears that you will have to deal with the subfolders explicitly.
As in, either the module polygon will have to import delaunay as polygon.delaunay.
Or module names will have to be appended to package.path so that lua could search through subfolders for filenames:
package.path=package.path..";./polygon/?.lua"
More info is here.
It is pointed out in comments, you'd probably want to ensure that path concatenation happens only once.
Also, one should be wary of name shadowing.
Finally, while we are at stirring up the past, a pretty nifty trick to solve the issue was proposed here five years before the question.
File.rename(blog_path + '/' + project_path, File.expand_path(topic_name, blog_path))
I use these code to rename ruby file name, but I think there is a better way to write this functionality with less code since it includes blog_path two times.
The code is OK, but I think there is no need to expand_path here - this method creates an absolute path from the the relative one.
Also, it is good to use File.join to create a path instead just concatenate it with slash - it will be completely OS independent. So I would write your code like this:
File.rename(File.join(blog_path, project_path), File.join(blog_path, topic_name))
Or if you want to get rid of doubled blog_path, change working directory before doing a rename:
Dir.chdir(blog_path)
File.rename(project_path, topic_name)
More info on working with files and directories in Ruby you can find in the article: Ruby for Admins: Files and Directories.
In terminal i could have used something like:
mv *.ext /some/output/dir/
I want to so the same in ruby. I can use system command for that under backticks (`) or using the system(), but how to achieve the same in ruby way?
I tried:
FileUtils.mv '*.sql', '/some/output/dir/'
This is not working as it looks specifically for a file name '*.sql'
You can do:
FileUtils.mv Dir.glob('*.sql'), '/some/output/dir/'
You need to use a Glob, as in:
Dir.glob('*.sql').each do|f|
# ... your logic here
end
or more succinct:
Dir.glob('*.sql').each {|f| FileUtils.mv(f, 'your/path/here')}
Check the official documentation on FileUtils#mv which has even an example with Glob.
Update: If you want to be sure you don't iterate (although I wouldn't worry about it that much) you can always execute what you consider to be optimized in shell, directly from ruby, e.g.:
`mv *.ext /some/output/dir/`
I will do using FileUtils::cp, as it copies a file content src to dest. If dest is a directory, copies src to dest/src. If src is a list of files, then dest must be a directory.
FileUtils.cp Dir['*.sql'], '/some/output/dir/'
I wouldn't use ::mv, as if file and dest exist on the different disk partition, the file is copied then the original file is removed.
But if you don't bother with the deletion of the original files, then go with ::mv.
I am trying to test the contents of a file that is generated from code. The problem is that the full name of the file is based on a timestamp abc123_#{d.strftime('%Y%m%d%I%M%S')}.log
How could I use File to find this file and read it? I tried doing File.exists?() with a regular expression as the parameter but that didn't work.
I found this in another question on stackoverflow:
File.basename(file_path).match(/_.*(css|scss|sass)/)
How would I be able to use that in my case where the file is located in mypublic folder?
ANSWER
So the two answers below both work and I used a combination of them.
Dir['public/*.log'].select { |f| f =~ /purge_cc_website/}
The * acts as a wildcard that is sort of a regular expression in itself. After that you filter the array using an actual regex.
Dir[] takes a file glob so, if your pattern isn't too complicated, you can just do:
Dir['public/abc123_*.log']
More glob info here.
File is for reading one file. You need to use Dir to find files by name.
files = Dir['*'].select {|x| x =~ /_.*(css|scss|sass)/ }
If you just want the last file in the case of dups:
files = Dir['*'].select {|x| x =~ /_.*(css|scss|sass)/ }.sort.last