Project

General

Profile

Actions

Feature #643

closed

__DIR__

Added by trans (Thomas Sawyer) over 15 years ago. Updated almost 13 years ago.

Status:
Rejected
Target version:
[ruby-core:19315]

Description

=begin
There is an snippet of code found in many Ruby scripts, especially testing scripts. It is...

File.dirname(FILE)

For something so common --and something that can not, by its very nature, be put into a reusable method, it is annoying to have to repeatedly calculate the current scripts location. So I respectfully request that a future version of Ruby provide a built-in reference that can be used instead:

DIR

This will improve readability, remove the need for extra variables to store this information, and at the very least, save us a good many keystrokes.
=end

Actions #1

Updated by zenspider (Ryan Davis) over 15 years ago

=begin

On Oct 13, 2008, at 11:27 , Thomas Sawyer wrote:

DIR

This will improve readability, remove the need for extra variables
to store this information, and at the very least, save us a good
many keystrokes.

yes.

I frequently need to do:

File.dirname(File.dirname(__FILE__))

so I'd like

__DIRDIR__

can we also have

__DIRDIRDIR__

while you're in there?

=end

Actions #2

Updated by pragdave (Dave Thomas) over 15 years ago

=begin

On Oct 13, 2008, at 4:51 PM, Phil Hagelberg wrote:

If we don't want to add another toplevel constant, another way to
handle
this gracefully would be to have the default argument for File.dirname
be the caller's FILE. At least 90% of the File.dirname invocations
that I write have FILE as their argument, so this would remove a
good deal of redundancy.

But with relative_require, suddenly most of those use cases evaporate,
no?

Dave

=end

Actions #3

Updated by duerst (Martin Dürst) over 15 years ago

=begin
Just some alternatives for everybody. What about
DIR__DIR__DIR instead of DIRDIRDIR?
Seems easier to count the levels. For those who
want to type less, maybe we can choose
DIR_DIR_DIR as a compromize?

Anyway, I think one problem with using File.dirname,
in particular repeatedly, is that it's rather long.
And the reason it's long is that it's not really
object-oriented.

So we should work towards something like FILE.dir.dir.dir,
which is easier to read and much shorter.

Regards, Martin.

At 04:08 08/10/14, Ryan Davis wrote:

On Oct 13, 2008, at 11:27 , Thomas Sawyer wrote:

DIR

This will improve readability, remove the need for extra variables
to store this information, and at the very least, save us a good
many keystrokes.

yes.

I frequently need to do:

File.dirname(File.dirname(FILE))

so I'd like

DIRDIR

can we also have

DIRDIRDIR

while you're in there?

#-#-# Martin J. Du"rst, Assoc. Professor, Aoyama Gakuin University
#-#-# http://www.sw.it.aoyama.ac.jp

=end

Actions #4

Updated by nobu (Nobuyoshi Nakada) over 15 years ago

=begin
Hi,

At Tue, 14 Oct 2008 04:20:18 +0900,
Nikolai Weibull wrote in [ruby-core:19319]:

I realize that I'm responding to a joke, but wouldn't it perhaps be
nice if File.dirname took an optional second argument that allowed you
to specify how many levels up you want to go?

I like this idea too.

I actually implemented this at work, simply because I was doing a lot
of nested File.dirname calls.

This is my patch.


Index: file.c

--- file.c (revision 19773)
+++ file.c (working copy)
@@ -2523,4 +2523,32 @@ rb_path_last_separator(const char *path)

static char *
+path_last_nth_separator(const char *pstart, const char *pend, int nth)
+{

  • enum {lastmax = 16};
  • char *lastbuf[lastmax];
  • if (nth <= 0) return (char *)pend;
  • do {
  • int lastidx = 0;
  • const char *path = pstart;
  • while (path < pend && *path) {
  •  if (isdirsep(*path)) {
    
  •  const char *tmp = path++;
    
  •  while (isdirsep(*path)) path++;
    
  •  if (!*path) break;
    
  •  lastbuf[lastidx++ % lastmax] = (char *)tmp;
    
  •  }
    
  •  else {
    
  •  path = CharNext(path);
    
  •  }
    
  • }
  • if (lastidx < nth) return NULL;
  • if (nth <= lastmax) return lastbuf[(lastidx - nth) % lastmax];
  • pend = lastbuf[lastidx % lastmax];
  • } while ((nth -= lastmax) > 0);
  • return (char *)pend;
    +}

+static char *
chompdirsep(const char *path)
{
@@ -3060,4 +3088,6 @@ rb_file_s_basename(int argc, VALUE *argv
}

+static VALUE rb_file_dirname(VALUE fname, int nth);
+
/*

  • call-seq:
    @@ -3073,11 +3103,22 @@ rb_file_s_basename(int argc, VALUE *argv

static VALUE
-rb_file_s_dirname(VALUE klass, VALUE fname)
+rb_file_s_dirname(int argc, VALUE *argv, VALUE klass)
+{

  • VALUE fname, level;
  • int nth;
  • rb_scan_args(argc, argv, "11", &fname, &level);
  • nth = NUM2INT(level);
  • FilePathStringValue(fname);
  • return rb_file_dirname(fname, nth);
    +}

+static VALUE
+rb_file_dirname(VALUE fname, int nth)
{
const char *name, *root, *p;
VALUE dirname;

  • FilePathStringValue(fname);
  • name = StringValueCStr(fname);
  • name = RSTRING_PTR(fname);
    root = skiproot(name);
    #ifdef DOSISH_UNC
    @@ -3088,5 +3129,21 @@ rb_file_s_dirname(VALUE klass, VALUE fna
    name = root - 1;
    #endif
  • p = strrdirsep(root);
  • if (nth < 0) {
  • const char *tmp = p = root;
  • while (++nth < 0) {
  •  while (isdirsep(*tmp)) tmp++;
    
  •  if (!(tmp = nextdirsep(p = tmp))) break;
    
  •  p = tmp;
    
  • }
  • }
  • else if (nth == 0) {
  • p = chompdirsep(root);
  • }
  • else if (nth == 1) {
  • p = strrdirsep(root);
  • }
  • else {
  • p = path_last_nth_separator(root, name + RSTRING_LEN(fname), nth);
  • }
    if (!p) {
    p = root;
    @@ -3209,5 +3266,5 @@ rb_file_s_split(VALUE klass, VALUE path)
    {
    FilePathStringValue(path); /* get rid of converting twice */
  • return rb_assoc_new(rb_file_s_dirname(Qnil, path), rb_file_s_basename(1,&path));
  • return rb_assoc_new(rb_file_dirname(path, 1), rb_file_s_basename(1,&path));
    }

@@ -4709,5 +4766,5 @@ Init_File(void)
rb_define_singleton_method(rb_cFile, "absolute_path", rb_file_s_absolute_path, -1);
rb_define_singleton_method(rb_cFile, "basename", rb_file_s_basename, -1);

  • rb_define_singleton_method(rb_cFile, "dirname", rb_file_s_dirname, 1);
  • rb_define_singleton_method(rb_cFile, "dirname", rb_file_s_dirname, -1);
    rb_define_singleton_method(rb_cFile, "extname", rb_file_s_extname, 1);
    rb_define_singleton_method(rb_cFile, "path", rb_file_s_path, 1);

--
Nobu Nakada

=end

Actions #5

Updated by trans (Thomas Sawyer) over 15 years ago

=begin

On Oct 13, 6:02 pm, Dave Thomas wrote:

On Oct 13, 2008, at 4:51 PM, Phil Hagelberg wrote:

If we don't want to add another toplevel constant, another way to  
handle
this gracefully would be to have the default argument for File.dirname
be the caller's FILE. At least 90% of the File.dirname invocations
that I write have FILE as their argument, so this would remove a
good deal of redundancy.

But with relative_require, suddenly most of those use cases evaporate,  
no?

Pretty much, but it would take a #relative_load and a
File.relative_read to really cover all common uses. But there are
always those outlay cases too. The thing about DIR is that it is
generally useful for all cases, whereas #relative_require has a single
specific use.

T.

=end

Actions #6

Updated by trans (Thomas Sawyer) over 15 years ago

=begin

On Oct 13, 3:08 pm, Ryan Davis wrote:

On Oct 13, 2008, at 11:27 , Thomas Sawyer wrote:

 DIR

This will improve readability, remove the need for extra variables  
to store this information, and at the very least, save us a good  
many keystrokes.

yes.

I frequently need to do:

   File.dirname(File.dirname(FILE))

so I'd like

   DIRDIR

can we also have

   DIRDIRDIR

while you're in there?

It's one thing to be sarcastic, it is another to be untruthful. If you
are actually using File.dirname(File.dirname(FILE)) "frequently",
then you need to rethink your design. But I know you are a better
coder than that. So you're simply not being sincere, and thus not
making a valid point.

T.

=end

Actions #7

Updated by trans (Thomas Sawyer) over 15 years ago

=begin

On Oct 15, 11:00 am, Aaron Patterson
wrote:

Yes Ryan.  Please stop the lies.  It hurts us all.

I did not say Ryan lied. I said he was being insincere in his response
to my suggestion.

Unfortunately, via your blog (http://tenderlovemaking.com/) I came
upon Ryan's lovely post:

http://blog.zenspider.com/2008/10/ranty-mcrantalots-reply-to-a-d.html

In which he does lie, and slanders and otherwise exhibits deplorable
behavior.

It's no wonder Zed Shaw left as he did. If this is what an influential
portion of the Ruby community has boiled down to --a clique of
miscreant bullies, I wouldn't be surprised if more follow suite.

T.

=end

Actions #8

Updated by ko1 (Koichi Sasada) over 15 years ago

  • Assignee set to matz (Yukihiro Matsumoto)

=begin

=end

Actions #9

Updated by yugui (Yuki Sonoda) over 15 years ago

  • Target version set to 2.0.0

=begin

=end

Actions #10

Updated by naruse (Yui NARUSE) over 14 years ago

  • Status changed from Open to Rejected

=begin

=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0