I was wondering something. I see this all the time at the top of files, or some variation of it that uses File.join. Another approach is to augment the load path, or $:
Since this is such a common idiom, why hasn't it been converted into a gem? What I think is the reason, is because in order to do one require, you'd have to do 2 other ones: rubygems, and the gem that had the File.expand_path. Also, the __FILE__ would have to be passed in, since it would be different for the gem .rb file.
But, 1.9 has gems built in. So for that, it would make sense if you had to require a lot of files. Something like:
Seems, this discussion has been going on for a while. Matz has consistently turned it down for core, but it seems to be in my 1.9.1 compiled for Mac, anyway, though the Internets say it is scheduled for 1.9.2.
My guess is it isn't portable, at least not to the 1.8.x crowd (LUsers :)
HaHa.
I also don't like that it takes a single argument, instead of *paths. Again I wonder about the Windows users. Also, I do like that it doesn't need __FILE__, since it extends module Kernel and uses the caller[0] for that.
On Thu, Oct 29, 2009 at 1:09 PM, Ed Howland <ed.howl...@gmail.com> wrote: > Hey guys. How's the weather there? Cold here.
> I was wondering something. I see this all the time at the top of > files, or some variation of it that uses File.join. Another approach > is to augment the load path, or $:
> Since this is such a common idiom, why hasn't it been converted into a > gem? What I think is the reason, is because in order to do one > require, you'd have to do 2 other ones: rubygems, and the gem that had > the File.expand_path. Also, the __FILE__ would have to be passed in, > since it would be different for the gem .rb file.
> But, 1.9 has gems built in. So for that, it would make sense if you > had to require a lot of files. Something like:
Yes, the File.expand_path/File.join idiom is used for systems that
don't follow the POSIX (UNIX) conventions for using forward slashes
(/) as path separator.
> How's the weather there? Cold here.
Cold and rainy. We've had more rain this October than any on record.
> I was wondering something. I see this all the time at the top of
> files, or some variation of it that uses File.join. Another approach
> is to augment the load path, or $:
Yeah, it would be nice to have something more standard, instead of 3
or 4 different idioms.
I agree Jeff. Currently, I am using require_relative() which came in
the recent Ruby 1.9.1. It seems to be canon now, for instance, the
Ruby backports gem has it.
But if you are writing a gem or an app and you want to make it 1.8
compatible, then you'd have to resort to requiring backports, (an
unneeded dependency), or use the File.expand_path(...) method. I hope
that 1.8.8 addresses this. [1]
Also, I wish that along with require_relative(), they could provide a
similar facility for $LOAD_PATH. Such as add_load_path("../lib/"). If
you distribute your app with an internal local gems directory (ala
Rails - vendor/gems) this could be useful for third party gems that
require each other. There is an environment variable GEM_PATH and
GEM_HOME that can be manipulated. Although some consider that rude.
But, since rubygems is native in 1.9+, there ought to be a way to set
the load path easily for them.
Then there is also the ~/.gem directory which recently caused me some
issues. One thing that is useful in that regard is deploying Rails
apps on a hosting site that doesn't let you install gems in the
standard gem path path (I am mostly referring to gem supplied
executables like cucumber, spec).
Also, I saw a demo at the GRRUG Tuesday of a Sinatra add-on that
included a require remote facility. If the gem was not installed on
the local system, it fetched it first, installed it (~/.gem?) and then
required it. Sweet (for some scenarios). I'll find out more and share
it.
There is also "http-require" which really only works with pure Ruby
gems (no native compiles), I think.
Ed
[1] It's times like these when I miss the preprocessor macro facility in C.
If you do a "sudo gem install mygem", then it already checks the
current version of ruby to determine the gem path.
(/usr/local/lib/ruby/gems/1.9.1/gems ...) I'd like it to supply a
preprocessor macro that you could do in your gem file like this:
Then the actual gem file would get installed for the right Ruby version.
On Fri, Nov 6, 2009 at 5:37 PM, Jeff Barczewski
<jeff.barczew...@gmail.com> wrote:
> I agree Ed, it is crazy to be still using File.dirname(__FILE__) which
> reminds me of C macros to do something that is extremely common.
> If nothing else, I'd like to see __DIR__ to at least eliminate the above.
> It is hard to believe how sometimes people get so entrenched against an idea
> rather than coming up with a real solution.
I don;t know if there is one. I know of a lot of bugs fixed in 1.6.7.
Maybe it will just be a patch level release.
O know you can do it in Ruby, but I was hoping to be able to provide
the gem installer with a hint about which version dir to drop the
library file into once it has been preprocessed. There is talk about
providing multiple architecture gems, and I hope that translates into
multiple ruby environments as well.
On that note, Robert Citek and I came up with a nice way to
switch between ruby 1.6 and 1.9.1 on Ubuntu Karmic. If you install
both 1.8 and 1.91 via apt-get, you get the 1.9.1 versions with 1.9,1
appended to each executable (/usr/bin/ruby1.9.1, /usr/bin/irb1.9.1
etc.).
Then set up ~/bin/ making sure it is first in you path. Create 2
scripts to ln the desired executables to ~/bin/ruby, ~/bin/irb
whatever. This is only viable for personal development. Not for
system-wide deployment.
BTW, Cucumber and RSpec install and work just fine under both if you
install twice via sudo gem install using both versions of Ruby (need
to double check that, tho). Then you should be able to cross-check
with your regression tests.
Upcoming blog post about this. Stay tuned.
Cheers
Ed,
Too god a day to be on the cimputer. See ya later!
On Mon, Nov 9, 2009 at 1:25 PM, Ed Howland <ed.howl...@gmail.com> wrote: > On that note, Robert Citek and I came up with a nice way to > switch between ruby 1.6 and 1.9.1 on Ubuntu Karmic. If you install > both 1.8 and 1.91 via apt-get, you get the 1.9.1 versions with 1.9,1 > appended to each executable (/usr/bin/ruby1.9.1, /usr/bin/irb1.9.1 > etc.).
Have you tried RVM [1]? I'm using it on Ubuntu Karmic. I also have a project called pik[2], which does something similar for windows users.
I like the Ramaze implementation of __DIR__(*args)
But there seems to be a difference between ruby versions wrt to
caller. On 1.9.1, I get something like this for caller[0]:
"/Users/edh/ruby/caller.rb:7:in `b'"
The path is fully expanded.
in 1.8.7:
rvm 1.8.7
irb
irb(main):006:0> caller[0][0][/^(.*):\d+:/,1]
=> "./caller.rb" # (within a method)
The path seems to be relative, depending on how the file was called.
But File.expand_path() works with this.
Note the extra colon, e.g. ":7:" which breaks Ramaze's regex
caller[0][/^(.*):/, 1] => "/Users/edh/ruby/caller.rb:7"
Note we get the line number too. I changed it to:
caller[0][/^(.*):\d+:/, 1]
=> "/Users/edh/ruby/caller.rb"
And it works:
(Extract the module Object from Ramaze's file and rename it to class Object).
irb(main):011:0* load "./dir.rb"
=> true
irb(main):006:0> Dir.chdir(__DIR__("run-calc", "features", "support")) do
irb(main):007:1* puts Dir.glob("*.rb")
irb(main):008:1> end
env.rb
paths.rb
Can anyone explain how :
[/^(.*):\d+:/,1]
works?
Overall, I hope Matz implements something like this feature.
> Maybe someone needs to simply create a patch and submit it to this thread??
> Jeff
> --
> You received this message because you are subscribed to the Google Groups
> "Saint Louis Ruby Users Group" group.
> To post to this group, send email to stlruby@googlegroups.com.
> To unsubscribe from this group, send email to
> stlruby+unsubscribe@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/stlruby?hl=.
> I like the Ramaze implementation of __DIR__(*args)
I don't much care for allowing __DIR__ to take args as a method.
__FILE__ is just a constant String, and I think __DIR__ should mirror
its implementation as much as possible.
> Can anyone explain how :
> [/^(.*):\d+:/,1]
> works?
The regex matches up until it reaches a colon, some digits (\d+), and
another colon. Then it stores what got matched within the parentheses.
Since it's the first open paren, it stores it into match variable 1.
The [regex, match_num] idiom in Ruby is pretty cool -- it makes it
easy to grab a piece of a string using a matching regex. I wish I
could find some online documentation on it (online docs for __FILE__
seem to be hard to find too). I'd bet it's in the better Ruby books
though.
BTW, I just found this alternative idiom for the equivalent to
__DIR__:
There is some discussion on this in the Ruby dev list (where Matz
hangs out). I'm not sure where he is going to end up, #Kernel.__dir__,
__dir__(*paths), __DIR__ or __DIR__(*paths). I think the consensus
might be for __DIR__ as a constant as you say. You can write your own
function that does a similar thing, assuming __DIR__ exists:
def relative_path(*paths)
File.join(__DIR__, *paths)
end
As far as "string"[/.../,1], goes, I got the regex, but this is a cool
idiom, nonetheless.
The docs are sort of buried in the String class doc(#5 below)::
from [1]:
str[fixnum] => fixnum or nil
str[fixnum, fixnum] => new_str or nil
str[range] => new_str or nil
str[regexp] => new_str or nil
str[regexp, fixnum] => new_str or nil
str[other_str] => new_str or nil
str.slice(fixnum) => fixnum or nil
str.slice(fixnum, fixnum) => new_str or nil
str.slice(range) => new_str or nil
str.slice(regexp) => new_str or nil
str.slice(regexp, fixnum) => new_str or nil
str.slice(other_str) => new_str or nil
"If a Regexp is supplied, the matching portion of str is returned. If
a numeric parameter follows the regular expression, that component of
the MatchData is returned instead."
On Mon, Nov 23, 2009 at 11:35 AM, Craig Buchek <craig.buc...@gmail.com> wrote:
>> I like the Ramaze implementation of __DIR__(*args)
> I don't much care for allowing __DIR__ to take args as a method.
> __FILE__ is just a constant String, and I think __DIR__ should mirror
> its implementation as much as possible.
>> Can anyone explain how :
>> [/^(.*):\d+:/,1]
>> works?
> The regex matches up until it reaches a colon, some digits (\d+), and
> another colon. Then it stores what got matched within the parentheses.
> Since it's the first open paren, it stores it into match variable 1.
> The [regex, match_num] idiom in Ruby is pretty cool -- it makes it
> easy to grab a piece of a string using a matching regex. I wish I
> could find some online documentation on it (online docs for __FILE__
> seem to be hard to find too). I'd bet it's in the better Ruby books
> though.
> BTW, I just found this alternative idiom for the equivalent to
> __DIR__:
> File.expand_path('..', __FILE__)
> Nice!
> --
> You received this message because you are subscribed to the Google Groups "Saint Louis Ruby Users Group" group.
> To post to this group, send email to stlruby@googlegroups.com.
> To unsubscribe from this group, send email to stlruby+unsubscribe@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/stlruby?hl=.
Duh. I should have realized that I should look in the String class for
the [] method. Even crazier is the assignment form:
str[regexp, fixnum] = new_str
I had a hard time finding documentation for __FILE__. It turns out
that it's a Ruby keyword, and a pseudo-variable, like true/false/nil/
self. David Black added documentation for these in 1.9:
http://ruby-doc.org/docs/keywords/1.9/.