Refining the use of file joins or file expand_path

Robert K. wrote:

“require” is for loading library code (libs as parts of the
installation, self written libs as well as gems).

“load” is for explicitly forcing a file load and execution at a define
place in the source code.

Thanks for the clarification Robert and I like your distinction because
it makes more sense to me. With your example in place, I am using
require and load statements correctly then. The only thing I’ve been
doing with regard to load statements is defining an absolute load path
rather than a relative load path. Code execution in this example is the
loading of an xml source file (xrc) by wx_sugar.

Now, I don’t know Ocra and hence I can’t say anything about it. My
approach is this: I have environment variable RUBYLIB set to an
absolute path where I place my own written libs (“${HOME}/lib/ruby” in
my case). I don’t have any gems installed on the system I am working
on so no requirements there. But generally the usage model of
“require” is that there is a list of entry points (partly built into
the interpreter, partly provided by the user e.g. via $RUBYLIB) which
are searched - which also means you generally use only relative paths
with require. This is also true for recursive requires - which can be
autoloads as well. See here for an example:

This is strange because I don’t know why I never thought about doing
this with Ruby. I’m so used to keeping my projects separate and
therefore, I tend to keep the libs separate. However, I could see
defining a libs dir for reusable library classes that I require in
future projects. Then, all I would have to do is require and/or include
the code I need. Ocra does look over the rubyopt variables set at the
time of processing. I’ll have to check the $: to see that my custom lib
directories are being set properly and included, but I can definitely
see this being a better way of implementing things later on. I can
privatize and store all my libs on github for safekeeping and rdoc
everything for my own benefit.

Robert this actually helps me out a lot because I want to write my own
custom modules for use with wxruby and I can define the namespaces and
just extend off those modules through dialogblocks when I generate my
elements and xrc source.

muppet-laboratories/lib/animal.rb at master · rklemme/muppet-laboratories · GitHub

I have not looked into autoloads at all. I’ll read up on them.

Turning back to your original example: it looks like what you really
want is to do “require ‘ui’” and have a file “ui.rb” located somewhere
in your library path which then consists mainly (or only) of “require
‘ui/a’” lines. “a.rb” then would be placed in directory /ui, i.e.
below the directory which contains file “ui.rb”.

No, that’s not what the issue was in this case. The ui.rb file is
actually a file called xrcframemain.rb which is automatically generated
by xrcise. This is one file that will always change in any application
that is created. So, it’s a roaming ruby file depending on which
project I’m in. Inside of this file, there is a custom xml.load
statement being used by wx_sugar to read xml source from an xrc file
that’s generated by most GUI designer apps. This xml file contains
information pertaining to GUI element positioning and also ties IDs to
instance variables that will be used in the app, as well as sub-class
element tags that are used to extend into modules. So, together, the
xrcframemain.rb and the ui.xrc files combine into a separate but usable
structure where program code is kept separate from design code.

So, I won’t change the requires for this particular file. At the
moment, I’m not having issues with any of my requires. Everything is
working well. However, with your input and suggestions, I am going to
change my whole way of thinking in terms of consolidating lib files for
use with wxruby.

Hope that helps.

Kind regards

robert

It does - my thanks!

Robert K. wrote:

Well, you can even have a mix of both: you can set RUBYLIB to your
“shared libs” folder and then in every main executable add an
appropriate folder of your local project. And we’re back to the
original question IIRC. :slight_smile: If you have to do that on multiple
machines though then it might be reasonable to use gems for
distribution and use the gems mechanism as storage for the shared
libs. But the principle would be the same.

Hi Robert, I just wanted to thank you once again for your advice. I
created a custom libs folder yesterday and moved a lot of source code
with regard to public instance methods for the main gui objects I work
with. It took some time to set it all up, but it’s working great. I
even created a rake task that pulls in the shared lib documentation for
classes I’m using in the project so that it’s also built with my app.

The only special event I did with my main lib folder was set an absolute
lib path:

$lib_path = FILE

… so that when I do have to use load methods from the RUBYLIB location,
the file path can still be maintained for the working project directory.

def set_icon_file(path, *file)
icon_file = File.join(File.dirname(path), file)
set_icon Wx::Icon.new(icon_file, Wx::BITMAP_TYPE_ICO)
end

and I can then use set_icon_file($lib_path, “icons”, “test.ico”)

… so everything is working fine now with regard to using my custom libs
with my project libs. I’m only placing methods and classes that will
absolutely be marked as reusable code.

My thanks again.

Alpha B. wrote:

The question I have (because I have written used both) is which would
“you” use and why keeping the following in mind…

Dir[File.join(File.dirname(FILE),“…”,“ui”,“*.rb”)].each {|rb_files|
load rb_files}

BTW, there’s an alternative to explicit use of File.join() which makes
the code more aesthetic:

To define String#/, like this:

class String
def /(o)
File.join(self, o.to_s)
end
end

and then you can do:

Dir[File.dirname(FILE) / “…” / “ui” / “*.rb”]

or even:

Dir[File.dirname(FILE) / “…” / :some / :path / “*.rb”]

I once investigated whether File.join() is needed and got the impression
that one can just use ‘/’ and things would work. Also, see this:

http://rubyforge.org/tracker/index.php?func=detail&aid=13026&group_id=426&atid=1698

Yet I see some Ruby gurus using File.join().

Dir[File.join(File.dirname(FILE),“…”,“ui”,“*.rb”)].each {|rb_files|
load rb_files}

There’s a problem in this approach: if you have a class the inherits
from a base class, you need to load the base class first. Dir[] gives
you random order(?), which is bad.

Albert S. wrote:

Robert K. wrote:

Turning back to your original example: it looks like what you really
want is to do “require ‘ui’”

I don’t think it’s safe to do “require ‘ui’”. Some other library may a
have a file by the same name and Ruby may load it instead of ours.

So one should do “require ‘mylibrary/ui’” instead.

I use private namespaces for my own libraries. The provided examples
were simply put, examples. It’s good to showcase what is proper though,
and I’m sure someone else that may read this down the road will find it
useful.

With GUI programs, especially those that may be unpacked in a temp
directory, I only use absolute paths pertaining to the unpacked files.
For all other files I use Dir.getwd which provides the current working
directory.

Thanks.

On 02/05/2010 01:44 AM, Albert S. wrote:

Robert K. wrote:

Turning back to your original example: it looks like what you really
want is to do “require ‘ui’”

I don’t think it’s safe to do “require ‘ui’”. Some other library may a
have a file by the same name and Ruby may load it instead of ours.

So one should do “require ‘mylibrary/ui’” instead.

That was based on the example given and under the assumption that the
library’s name is “ui”. In that case you would use reqire ‘ui’.

Cheers

robert

Robert K. wrote:

Turning back to your original example: it looks like what you really
want is to do “require ‘ui’”

I don’t think it’s safe to do “require ‘ui’”. Some other library may a
have a file by the same name and Ruby may load it instead of ours.

So one should do “require ‘mylibrary/ui’” instead.

(Or one could feed require() an absolute path, but I don’t see people
doing this.)

Alpha B. wrote:

Also, if you accidentally nest a require, say for example:

–root
– app.rb
----\lib
---- main.rb
---- modules.rb

… note that modules.rb and main.rb are within the same directory
(main).

If your app.rb has require ‘lib/main’
… and
If your main.rb has require ‘modules’

Same problem. If some other library has ‘modules.rb’, Ruby may load if
instead of ours.

The directory structure should be:

–root
– app.rb
----\lib
-------myapp.rb (instead of ‘main.rb’)
-------\myapp
------- modules.rb

app.rb should push Dir.basename(FILE) + ‘/lib’ onto $: (if it’s not
already there). Then, it should require ‘myapp.rb’. myapp.rb should
‘require “myapp/modules.rb”’. Then there’s no risk that Ruby will load
other library’s files because, by having a ‘myapp’ subdir were
effectively creating a namespace.