Seeking advice on some method names

Discussion in 'Ruby' started by Gavin Sinclair, Nov 29, 2004.

  1. Hi all,

    I'm preparing some methods for 'extensions' [1] and would like some
    people's opinions on method names.

    Array#only
    [5].only -> 5
    [1,2,3].only -> exception

    Class.get_class
    Class.get_class("Test::Unit") -> Test::Unit
    Class.get_class("not-a-class") -> exception

    # Should 'get_class' be in Class or in Kernel?

    Class#bare_name
    Test::Unit.bare_name -> "Unit"

    String#line_wrap
    "the quick brown fox jumps ...".line_wrap(10)
    -> "the quick
    brown fox
    jumps ..."

    Thanks,
    Gavin

    [1] http://extensions.rubyforge.org
     
    Gavin Sinclair, Nov 29, 2004
    #1
    1. Advertising

  2. Gavin Sinclair

    James Britt Guest

    Gavin Sinclair wrote:
    > Hi all,
    >
    > I'm preparing some methods for 'extensions' [1] and would like some
    > people's opinions on method names.
    >
    > Array#only
    > [5].only -> 5
    > [1,2,3].only -> exception
    >
    >


    What is 'only' supposed to do?


    James
     
    James Britt, Nov 29, 2004
    #2
    1. Advertising

  3. On Monday, November 29, 2004, 2:06:25 PM, James wrote:

    > Gavin Sinclair wrote:
    >> Hi all,
    >>
    >> I'm preparing some methods for 'extensions' [1] and would like some
    >> people's opinions on method names.
    >>
    >> Array#only
    >> [5].only -> 5
    >> [1,2,3].only -> exception
    >>
    >>


    > What is 'only' supposed to do?


    Return the _only_ element in an array. If there's not exactly one,
    then "only" doesn't make sense, so an exception is raised. (At the
    moment, the exception is RangeError, but I need to think about that.)

    Gavin
     
    Gavin Sinclair, Nov 29, 2004
    #3
  4. On Monday, November 29, 2004, 1:57:50 PM, itsme213 wrote:

    >> Array#only
    >> [5].only -> 5
    >> [1,2,3].only -> exception


    > I prefer: Array#one
    > to be complemented by
    > Array#one? #{|e| predicate(e)} true if exactly one match


    > and rounded out by

    Array#any #=>> return a random element, like Array#any?
    > Array#none # with addition of Array#none? {|e| predicate(e)}

    Array#all #=>> of questionable value

    > and separately
    > Array#include_all? (other_enumerable)


    #any? and #all? are methods of Enumerable, not Array. I like the idea
    of Enumerable#one? and Enumerable#none? to complement them.

    But I don't think Enumerable#one? and Array#one are complementary;
    they seem entirely different.

    Likewise with Array#any: it's useful, but really has nothing to do
    with #any? I'm implementing Array#rand, by the way.

    Regarding Array#include_all?, you might want to look at Set.

    Cheers,
    Gavin
     
    Gavin Sinclair, Nov 29, 2004
    #4
  5. On Mon, 29 Nov 2004 11:31:06 +0900, Gavin Sinclair
    <> wrote:
    > Class.get_class
    > Class.get_class("Test::Unit") -> Test::Unit
    > Class.get_class("not-a-class") -> exception
    >
    > # Should 'get_class' be in Class or in Kernel?


    Why not String?
    "Test::Unit".to_class # => Test::Unit

    My justification: it's analogous to String#to_sym.

    > Thanks,
    > Gavin


    Sam
     
    Sam Stephenson, Nov 29, 2004
    #5
  6. Hi --

    On Mon, 29 Nov 2004, Sam Stephenson wrote:

    > On Mon, 29 Nov 2004 11:31:06 +0900, Gavin Sinclair
    > <> wrote:
    > > Class.get_class
    > > Class.get_class("Test::Unit") -> Test::Unit
    > > Class.get_class("not-a-class") -> exception
    > >
    > > # Should 'get_class' be in Class or in Kernel?

    >
    > Why not String?
    > "Test::Unit".to_class # => Test::Unit
    >
    > My justification: it's analogous to String#to_sym.


    I'm not sure what either of these adds to const_get -- or, to put it
    another way, why there should be a special method to do (essentially)
    a const_get only for strings that represent class names.


    David

    --
    David A. Black
     
    David A. Black, Nov 29, 2004
    #6
  7. Gavin Sinclair

    Jamis Buck Guest

    David A. Black wrote:
    > Hi --
    >
    > On Mon, 29 Nov 2004, Sam Stephenson wrote:
    >
    >
    >>On Mon, 29 Nov 2004 11:31:06 +0900, Gavin Sinclair
    >><> wrote:
    >>
    >>> Class.get_class
    >>> Class.get_class("Test::Unit") -> Test::Unit
    >>> Class.get_class("not-a-class") -> exception
    >>>
    >>> # Should 'get_class' be in Class or in Kernel?

    >>
    >>Why not String?
    >> "Test::Unit".to_class # => Test::Unit
    >>
    >>My justification: it's analogous to String#to_sym.

    >
    >
    > I'm not sure what either of these adds to const_get -- or, to put it
    > another way, why there should be a special method to do (essentially)
    > a const_get only for strings that represent class names.


    Well, IIRC, const_get doesn't work with symbols that contain "::". In
    other words, const_get( "Test::Unit" ) would fail--you'd have to do
    const_get("Test").const_get("Unit"), which becomes cumbersome. I can
    think of several instances in my Net::SSH and Net::SFTP stuff alone
    where a standard #get_class method would have been useful (though far
    from necessary).

    - Jamis

    --
    Jamis Buck

    http://www.jamisbuck.org/jamis
     
    Jamis Buck, Nov 29, 2004
    #7
  8. Hi --

    On Mon, 29 Nov 2004, Jamis Buck wrote:

    > David A. Black wrote:
    > > Hi --
    > >
    > > On Mon, 29 Nov 2004, Sam Stephenson wrote:
    > >
    > >
    > >>On Mon, 29 Nov 2004 11:31:06 +0900, Gavin Sinclair
    > >><> wrote:
    > >>
    > >>> Class.get_class
    > >>> Class.get_class("Test::Unit") -> Test::Unit
    > >>> Class.get_class("not-a-class") -> exception
    > >>>
    > >>> # Should 'get_class' be in Class or in Kernel?
    > >>
    > >>Why not String?
    > >> "Test::Unit".to_class # => Test::Unit
    > >>
    > >>My justification: it's analogous to String#to_sym.

    > >
    > >
    > > I'm not sure what either of these adds to const_get -- or, to put it
    > > another way, why there should be a special method to do (essentially)
    > > a const_get only for strings that represent class names.

    >
    > Well, IIRC, const_get doesn't work with symbols that contain "::". In
    > other words, const_get( "Test::Unit" ) would fail--you'd have to do
    > const_get("Test").const_get("Unit"), which becomes cumbersome. I can
    > think of several instances in my Net::SSH and Net::SFTP stuff alone
    > where a standard #get_class method would have been useful (though far
    > from necessary).


    Oh right, I forgot about that. There are some "deep" const_get
    implementations floating around... along the lines of:

    def deep_const_get(str)
    str.split('::').inject(Object) {|a,b| a.const_get(b) }
    end

    which might help.


    David

    --
    David A. Black
     
    David A. Black, Nov 29, 2004
    #8
  9. On Mon, 29 Nov 2004 13:34:24 +0900, David A. Black <> wrote:
    > Hi --
    >
    >
    >
    > On Mon, 29 Nov 2004, Sam Stephenson wrote:
    >
    > > On Mon, 29 Nov 2004 11:31:06 +0900, Gavin Sinclair
    > > <> wrote:
    > > > Class.get_class
    > > > Class.get_class("Test::Unit") -> Test::Unit
    > > > Class.get_class("not-a-class") -> exception
    > > >
    > > > # Should 'get_class' be in Class or in Kernel?

    > >
    > > Why not String?
    > > "Test::Unit".to_class # => Test::Unit
    > >
    > > My justification: it's analogous to String#to_sym.

    >
    > I'm not sure what either of these adds to const_get


    AFAIK, const_get doesn't handle objects below its namespace, so you
    can't const_get 'Foo::Bar', you have to Foo.const_get 'Bar'.

    > -- or, to put it
    > another way, why there should be a special method to do (essentially)
    > a const_get only for strings that represent class names.


    I agree. Maybe String#to_const would be more appropriate?

    > David
    >
    > --
    > David A. Black
    >


    Sam
     
    Sam Stephenson, Nov 29, 2004
    #9
  10. Gavin Sinclair

    Jim Weirich Guest

    > On Mon, 29 Nov 2004, Sam Stephenson wrote:
    > > Why not String?
    > > "Test::Unit".to_class # => Test::Unit


    On Sunday 28 November 2004 11:34 pm, David A. Black wrote:
    > I'm not sure what either of these adds to const_get -- or, to put it
    > another way, why there should be a special method to do (essentially)
    > a const_get only for strings that represent class names.


    Why? Because it is a common function that is easy to do wrong. The quick and
    obvious choices (eval(string) and Object.const_get(string)) are flawed. And
    the one-liner that does it correctly ...

    string.split("::").inject(Object) { |ns, n| ns.const_get(n) }

    ... is hardly transparent.

    It is a common enough activity that having a standard and canonical way of
    converting strings to classes would ease a number of tasks (e.g. anytime you
    wish to specify a class in a config file, input stream or data base).

    --
    -- Jim Weirich http://onestepback.org
    -----------------------------------------------------------------
    "Beware of bugs in the above code; I have only proved it correct,
    not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
     
    Jim Weirich, Nov 29, 2004
    #10
  11. Gavin Sinclair

    Carlos Guest

    [Gavin Sinclair <>, 2004-11-29 03.31 CET]
    > Class.get_class
    > Class.get_class("Test::Unit") -> Test::Unit
    > Class.get_class("not-a-class") -> exception


    Class.for_name, as in java.

    > # Should 'get_class' be in Class or in Kernel?


    in Module, maybe?
     
    Carlos, Nov 29, 2004
    #11
  12. On Monday, November 29, 2004, 3:53:43 PM, David wrote:

    >> > I'm not sure what either of these adds to const_get -- or, to put it
    >> > another way, why there should be a special method to do (essentially)
    >> > a const_get only for strings that represent class names.

    >>
    >> Well, IIRC, const_get doesn't work with symbols that contain "::". In
    >> other words, const_get( "Test::Unit" ) would fail--you'd have to do
    >> const_get("Test").const_get("Unit"), which becomes cumbersome. I can
    >> think of several instances in my Net::SSH and Net::SFTP stuff alone
    >> where a standard #get_class method would have been useful (though far
    >> from necessary).


    > Oh right, I forgot about that. There are some "deep" const_get
    > implementations floating around... along the lines of:


    > def deep_const_get(str)
    > str.split('::').inject(Object) {|a,b| a.const_get(b) }
    > end


    > which might help.


    That's precisely how it's implemented in extensions. BTW it's now
    Class.by_name.

    Class.by_name("::Test::Unit") -> Test::Unit

    Gavin
     
    Gavin Sinclair, Nov 29, 2004
    #12
  13. On Mon, 29 Nov 2004 11:31:06 +0900
    Gavin Sinclair <> wrote:

    > Hi all,
    >
    > I'm preparing some methods for 'extensions' [1] and would like some
    > people's opinions on method names.
    >
    > Array#only
    > [5].only -> 5
    > [1,2,3].only -> exception
    >


    Maybe to_scalar would tell more clearly what it is doing?

    > Class.get_class
    > Class.get_class("Test::Unit") -> Test::Unit
    > Class.get_class("not-a-class") -> exception
    >
    > # Should 'get_class' be in Class or in Kernel?
    >


    I'd call it Class.by_name(sym)

    regards,

    Brian

    --
    Brian Schröder
    http://www.brian-schroeder.de/
     
    Brian Schröder, Nov 29, 2004
    #13
  14. Hi --

    On Mon, 29 Nov 2004, Gavin Sinclair wrote:

    > On Monday, November 29, 2004, 3:53:43 PM, David wrote:
    >
    > >> > I'm not sure what either of these adds to const_get -- or, to put it
    > >> > another way, why there should be a special method to do (essentially)
    > >> > a const_get only for strings that represent class names.
    > >>
    > >> Well, IIRC, const_get doesn't work with symbols that contain "::". In
    > >> other words, const_get( "Test::Unit" ) would fail--you'd have to do
    > >> const_get("Test").const_get("Unit"), which becomes cumbersome. I can
    > >> think of several instances in my Net::SSH and Net::SFTP stuff alone
    > >> where a standard #get_class method would have been useful (though far
    > >> from necessary).

    >
    > > Oh right, I forgot about that. There are some "deep" const_get
    > > implementations floating around... along the lines of:

    >
    > > def deep_const_get(str)
    > > str.split('::').inject(Object) {|a,b| a.const_get(b) }
    > > end

    >
    > > which might help.

    >
    > That's precisely how it's implemented in extensions. BTW it's now
    > Class.by_name.
    >
    > Class.by_name("::Test::Unit") -> Test::Unit


    Is this restricted to Class objects?


    David

    --
    David A. Black
     
    David A. Black, Nov 29, 2004
    #14
  15. On Sunday 28 November 2004 09:31 pm, Gavin Sinclair wrote:

    | Class#bare_name
    | Test::Unit.bare_name -> "Unit"

    Should it be congruent with File.basename? Other suggestion: #rootname.

    T.
     
    trans. (T. Onoma), Nov 29, 2004
    #15
  16. On Monday, November 29, 2004, 10:15:36 PM, David wrote:

    >> > Oh right, I forgot about that. There are some "deep" const_get
    >> > implementations floating around... along the lines of:

    >>
    >> > def deep_const_get(str)
    >> > str.split('::').inject(Object) {|a,b| a.const_get(b) }
    >> > end

    >>
    >> > which might help.

    >>
    >> That's precisely how it's implemented in extensions. BTW it's now
    >> Class.by_name.
    >>
    >> Class.by_name("::Test::Unit") -> Test::Unit


    > Is this restricted to Class objects?


    No. It's defined in Module as

    class Module
    def Module.by_name(name)
    name = name.to_str.sub(/^::([A-z])/, '\1')
    name.split(/::/).inject(Object) { |mod, name| mod.const_get(name) }
    end
    end

    So trailing constants in a path are accepted, like

    Shapes::Circle::MAX_RADIUS

    Hadn't thought of that...

    Gavin
     
    Gavin Sinclair, Nov 29, 2004
    #16
  17. On Monday, November 29, 2004, 11:55:38 PM, trans. wrote:

    > On Sunday 28 November 2004 09:31 pm, Gavin Sinclair wrote:


    > | Class#bare_name
    > | Test::Unit.bare_name -> "Unit"


    > Should it be congruent with File.basename? Other suggestion: #rootname.


    Good idea. I'm warming to Module.basename.

    Thanks,
    Gavin
     
    Gavin Sinclair, Nov 29, 2004
    #17
  18. On Monday 29 November 2004 08:39 am, Gavin Sinclair wrote:
    | On Monday, November 29, 2004, 11:55:38 PM, trans. wrote:
    | > On Sunday 28 November 2004 09:31 pm, Gavin Sinclair wrote:
    | > | Class#bare_name
    | > | Test::Unit.bare_name -> "Unit"
    | >
    | > Should it be congruent with File.basename? Other suggestion: #rootname.
    |
    | Good idea. I'm warming to Module.basename.

    This only problem I see is of course that:

    File.basename != "File"

    But that's probably too insignificant to worry about.

    T.
     
    trans. (T. Onoma), Nov 29, 2004
    #18
  19. On Monday, November 29, 2004, 9:56:12 PM, Brian wrote:

    > On Mon, 29 Nov 2004 11:31:06 +0900
    > Gavin Sinclair <> wrote:


    >> Hi all,
    >>
    >> I'm preparing some methods for 'extensions' [1] and would like some
    >> people's opinions on method names.
    >>
    >> Array#only
    >> [5].only -> 5
    >> [1,2,3].only -> exception
    >>


    > Maybe to_scalar would tell more clearly what it is doing?


    #to_scalar is not really clear to me. I can foce my mind to think
    that way, but it's not natural.

    But obviously #only has attracted its fair share of comment as well.
    It's very clear to me: return the _only_ element in the array.
    Perhaps people have never felt the need for it, which I understand.

    Gavin
     
    Gavin Sinclair, Nov 30, 2004
    #19
  20. On Tuesday, November 30, 2004, 1:52:49 AM, itsme213 wrote:

    >> But I don't think Enumerable#one? and Array#one are complementary;
    >> they seem entirely different.


    > Array#one {|x| pred} would complement Enumerable#one? {|x| pred}
    > so
    > Array#one
    > is same as Array#one{|x|true}
    > which complements Enumerable#one?{|x|true}


    >> Likewise with Array#any: it's useful, but really has nothing to do
    >> with #any?


    > Array#any{|x| pred} complements Enumerable#any? {|x| pred}
    > so
    > Array#any complements Enumerable#any?{|x|true}



    Two equivalent code samples:

    A)

    numbers.one { |n| n.prime? }
    numbers.any { |n| n.prime? }

    B)

    numbers.select { |n| n.prime? }.only
    numbers.select { |n| n.prime? }.rand

    I find (B) more intuitive. I'd rather see #select doing the
    selection, instead of introducing yet more methods that select
    elements. [1] Further, #rand and #only are telling me what
    they're doing. #one and #any are "merely" complements of
    #one? and #any?.

    To expand further, I find #any quite reasonable, but #rand more so.
    Array#rand is something I've implemented occasionally, and have seen
    other requests and references. I find #one quite uncompelling,
    because it sounds like #any: it doesn't express its one_and_only_one
    meaning.

    Cheers,
    Gavin

    [1] There are valid reasons to introduce more selection methods, but
    these don't qualify, to my mind.
     
    Gavin Sinclair, Nov 30, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. bill
    Replies:
    3
    Views:
    697
  2. iksrazal
    Replies:
    2
    Views:
    360
    enrique
    Apr 27, 2005
  3. Steve W. Jackson

    Seeking class hierarchy advice

    Steve W. Jackson, Apr 26, 2006, in forum: Java
    Replies:
    1
    Views:
    288
    Chris Uppal
    Apr 27, 2006
  4. Dave
    Replies:
    2
    Views:
    381
    David Harmon
    Apr 13, 2004
  5. NickName
    Replies:
    4
    Views:
    349
    NickName
    Dec 17, 2006
Loading...

Share This Page