Seeking advice on some method names

G

Gavin Sinclair

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
 
J

James Britt

Gavin said:
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
 
G

Gavin Sinclair

Gavin said:
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
 
G

Gavin Sinclair

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
 
S

Sam Stephenson

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
 
D

David A. Black

Hi --

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
 
J

Jamis Buck

David said:
Hi --




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
 
D

David A. Black

Hi --

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
 
S

Sam Stephenson

Hi --





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?

Sam
 
J

Jim Weirich

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).
 
G

Gavin Sinclair

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
 
B

Brian Schröder

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
 
D

David A. Black

Hi --

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
 
T

trans. (T. Onoma)

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.
 
G

Gavin Sinclair

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
 
T

trans. (T. Onoma)

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.
 
G

Gavin Sinclair

On Mon, 29 Nov 2004 11:31:06 +0900
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
 
G

Gavin Sinclair

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}
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top