Feature #5628
closedModule#basename
Added by trans (Thomas Sawyer) about 13 years ago. Updated about 4 years ago.
Description
Something I use fairly often:
some_module.name.split("::").last
It's useful for things like factory methods. It would be much nicer if we had:
class Module
def basename
name.split("::").last
end
end
Updated by wycats (Yehuda Katz) about 13 years ago
Totally agreed. This pattern is fairly common. It would also be nice to
have Module#modules or something, such that Foo::Bar would return [Foo,
Bar].
Yehuda Katz
(ph) 718.877.1325
On Sun, Nov 13, 2011 at 6:17 PM, Thomas Sawyer transfire@gmail.com wrote:
Issue #5628 has been reported by Thomas Sawyer.
Feature #5628: Module#basename
http://redmine.ruby-lang.org/issues/5628Author: Thomas Sawyer
Status: Open
Priority: Normal
Assignee:
Category:
Target version: 1.9.4Something I use fairly often:
some_module.name.split("::").last
It's useful for things like factory methods. It would be much nicer if we
had:class Module
def basename
name.split("::").last
end
end
Updated by agrimm (Andrew Grimm) about 13 years ago
I'm not sure about the method name. What should happen with File::basename ? Should it call super when there's no arguments, and do its own thing when called with an argument? I'd prefer Ruby to tell me that I forgot to pass in a string!
Updated by Eregon (Benoit Daloze) about 13 years ago
On 14 November 2011 07:32, Andrew Grimm andrew.j.grimm@gmail.com wrote:
Issue #5628 has been updated by Andrew Grimm.
I'm not sure about the method name. What should happen with File::basename ? Should it call super when there's no arguments, and do its own thing when called with an argument? I'd prefer Ruby to tell me that I forgot to pass in a string!
I also agree this would be useful.
But the name 'basename' is probably not the best.
I remember I used simple_name for this, but it's not appealing.
Updated by regularfry (Alex Young) about 13 years ago
On 14/11/11 10:19, Benoit Daloze wrote:
On 14 November 2011 07:32, Andrew Grimm andrew.j.grimm@gmail.com wrote:
Issue #5628 has been updated by Andrew Grimm.
I'm not sure about the method name. What should happen with File::basename ? Should it call super when there's no arguments, and do its own thing when called with an argument? I'd prefer Ruby to tell me that I forgot to pass in a string!
I also agree this would be useful.
But the name 'basename' is probably not the best.
I remember I used simple_name for this, but it's not appealing.
I like this - I use .split("::").last all over the place.
A few alternatives, since I agree it would be unfortunate to overload
.basename:
.inner_name
.last_name
.primary_name
.name( false )
.name( :full => false )
--
Alex
Updated by trans (Thomas Sawyer) about 13 years ago
@Andrew File::basename is a class method, where as Module#basename is an instance method, so there isn't really any "polymorphic confliction".
I think we'd also be hard pressed to find a better name. I've thought about it quite a bit. And nothing else seems to fit. Ironically #firstname makes the most semantic sense for English speakers. Since Ruby is Japanese in origin, then #lastname is a fun option to confound Americans ;)
I think #basename is best b/c there is a common correspondence between files and classes, eg. lib/foo/some_class
will usually contain Foo::SomeClass
. There is also Pathname#basename
.
Updated by Eregon (Benoit Daloze) about 13 years ago
On 14 November 2011 12:58, Thomas Sawyer transfire@gmail.com wrote:
Issue #5628 has been updated by Thomas Sawyer.
@Andrew File::basename is a class method, where as Module#basename is an instance method, so there isn't really any "polymorphic confliction".
Are you so sure? ;-)
A class method is an instance method on the class, so yes
File::basename conflicts with Module#basename:
class Module
def basename
name.split("::").last
end
end
Enumerator::Generator.basename
=> "Generator"
File.basename
ArgumentError: wrong number of arguments (0 for 1..2)
from (irb):7:in `basename'
File.basename 'file.ext'
=> "file.ext"
So one calling 'basename' on a Module can expect either a String or an
ArgumentError.
And changing File::basename to be Module#basename when no arguments
are given does not seem a good design at all.
Updated by trans (Thomas Sawyer) about 13 years ago
You're right. File is also Module (subclass of Class). So, yes, another name is needed, or ::File.basename accepted as an exception.
In my defense, I always thought File class methods for file handling were bad mojo! It would be much better if Pathname were core and File class methods non-existent (IMHO).
Updated by wycats (Yehuda Katz) about 13 years ago
I would probably be ok with mod.modules.last.name to be honest.
Yehuda Katz
(ph) 718.877.1325
On Mon, Nov 14, 2011 at 7:12 AM, Thomas Sawyer transfire@gmail.com wrote:
Issue #5628 has been updated by Thomas Sawyer.
You're right. File is also Module (subclass of Class). So, yes, another
name is needed, or ::File.basename accepted as an exception.In my defense, I always thought File class methods for file handling were
bad mojo! It would be much better if Pathname were core and File class
methods non-existent (IMHO).
Feature #5628: Module#basename
http://redmine.ruby-lang.org/issues/5628Author: Thomas Sawyer
Status: Open
Priority: Normal
Assignee:
Category:
Target version: 1.9.4Something I use fairly often:
some_module.name.split("::").last
It's useful for things like factory methods. It would be much nicer if we
had:class Module
def basename
name.split("::").last
end
end
Updated by trans (Thomas Sawyer) about 13 years ago
I would probably be ok with mod.modules.last.name to be honest.
Then might as well add mod.lastname too. If the implementation is anything like the pure-Ruby one, it is more efficient to have a dedicated method. And I much prefer the shorter syntax. If not #lastname then maybe #modname.
Updated by mame (Yusuke Endoh) over 12 years ago
- Assignee set to matz (Yukihiro Matsumoto)
Updated by mame (Yusuke Endoh) over 12 years ago
- Status changed from Open to Assigned
Updated by mame (Yusuke Endoh) over 12 years ago
- Target version changed from 1.9.4 to 2.0.0
Hello,
2011/11/14 Thomas Sawyer transfire@gmail.com:
Something I use fairly often:
some_module.name.split("::").last
Personally, I've never used such a hack. When do you use?
--
Yusuke Endoh mame@tsg.ne.jp
Updated by trans (Thomas Sawyer) over 12 years ago
Common case (for me) is when user selects a "plug-in" via a command line option. For example a pseudo test framework:
$ mytest --reporter progress
Then in code:
module MyTestFramework
def self.reporters
@reporters ||= {}
end
module Reporters
class Base
def self.inherited(subclass)
MyTestFramework.reporters[subclass.basename.downcase] = subclass
end
end
class Progress < Base
...
end
end
end
Then reporters are very easy to lookup with command line option.
MyTestFramework.reporters[reporter] # i.e. reporter = 'progress'
That's just one example, but I have found the basic pattern to be useful in many such "pluggable" designs.
Updated by regularfry (Alex Young) over 12 years ago
=begin
I'm doing something remarkably similar to this for mapping command-line subcommand selection into a module's namespace. It's very handy.
=end
Updated by matz (Yukihiro Matsumoto) over 12 years ago
- Status changed from Assigned to Feedback
I am not sure if it's worth adding to the core. It is so easy to add by third-party lib.
Besides that, even though the term "basename" is understandable from analogy to UNIX command name, but the term includes "base" might cause confusion, since "base" in object class has different meaning (especially C++ and other languages).
Matz.
Updated by trans (Thomas Sawyer) over 12 years ago
You are right about name, it would have to be something else besides #basename.
Yehuda Katz said he would probably be ok with mod.modules.last.name
, to which I commented, we may as well add mod.lastname
.
Updated by yhara (Yutaka HARA) about 12 years ago
- Target version changed from 2.0.0 to 2.6
Updated by fatkodima (Dima Fatko) about 4 years ago
Used this numerous times.
I like this suggestion:
regularfry (Alex Young) wrote in #note-4:
.name( false )
.name( :full => false )
What ruby-core think on this?