Noob: use of the double colon


#1

Hi,

there seems to be more than one way to execute class methods.
I’ve seen the form (I use the classmethod new as an example):
newObject = Classname::new
but also
newObject = Classname.new
Bothe seem to work OK.
Is there a difference? If yes, what is the difference?

Also I see :: being used in the context of modules. Can you tell me
about that as well?

Thanks!

Arie


#2

Hi –

On Sun, 26 Mar 2006, NuclearFusion wrote:

Hi,

there seems to be more than one way to execute class methods.
I’ve seen the form (I use the classmethod new as an example):
newObject = Classname::new
but also
newObject = Classname.new
Bothe seem to work OK.
Is there a difference? If yes, what is the difference?

They do both work. I’ve never understood why the :: exists for this
purpose, since the . is the normal way of sending messages to objects
and works perfectly well whether or not the receiver is a class. It’s
on my very short list of things I’d like to see removed from Ruby.

Also I see :: being used in the context of modules. Can you tell me
about that as well?

That’s for looking up names of constants in nested scopes:

module M
X = 1
end

puts M::X # 1

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#3

On Sun, 2006-03-26 at 22:33 +0900, removed_email_address@domain.invalid wrote:

newObject = Classname.new

That’s for looking up names of constants in nested scopes:

module M
X = 1
end

puts M::X # 1

While we’re on the topic – I’ve never exactly understood what placing
the double colon at the beginning does? eg…

::FooModule::FOO_CONSTANT

?

Cheers


#4

Hi –

On Sun, 26 Mar 2006, Jonathan L. wrote:

While we’re on the topic – I’ve never exactly understood what placing
the double colon at the beginning does? eg…

::FooModule::FOO_CONSTANT

?

It forces a top-level lookup. For example:

class M
class String
end

 def initialize
   @ms = String.new            # this will be M::String
   @str = ::String.new("abc")  # this will be top-level string
 end

end

It’s like a / at the beginning of a file path.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#5

Thanx for your clear answers David!
Arie


#6

On Sun, 2006-03-26 at 23:44 +0900, removed_email_address@domain.invalid wrote:

end

It’s like a / at the beginning of a file path.

Ah okay, thanks very much.


#7

On 3/26/06, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

newObject = Classname.new
Bothe seem to work OK.
Is there a difference? If yes, what is the difference?

They do both work. I’ve never understood why the :: exists for this
purpose, since the . is the normal way of sending messages to objects
and works perfectly well whether or not the receiver is a class. It’s
on my very short list of things I’d like to see removed from Ruby.

Some might say this is another example of TIMTOWTDI.
However, like you, I’d like to see it changed to only use “.”.

Also I see :: being used in the context of modules. Can you tell me
about that as well?

That’s for looking up names of constants in nested scopes:

module M
X = 1
end

puts M::X # 1

It seems to me that dots could be used for constant references too.
Maybe someone will point out a reason why this would complicate
parsing.


#8

Hi –

On Mon, 27 Mar 2006, Mark V. wrote:

but also
newObject = Classname.new
Bothe seem to work OK.
Is there a difference? If yes, what is the difference?

They do both work. I’ve never understood why the :: exists for this
purpose, since the . is the normal way of sending messages to objects
and works perfectly well whether or not the receiver is a class. It’s
on my very short list of things I’d like to see removed from Ruby.

Some might say this is another example of TIMTOWTDI.

They’d be right, but that’s the Perl slogan, not the Ruby slogan :slight_smile:
(even though it’s factually true of a number of things in Ruby)

puts M::X # 1

It seems to me that dots could be used for constant references too.
Maybe someone will point out a reason why this would complicate
parsing.

I’d rather just have a message-sending operator (.) and a
constant-lookup operator (::). These are completely different
operations, and I don’t think overlap in either direction is useful.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#9

On Sun, 26 Mar 2006 removed_email_address@domain.invalid wrote:

Bothe seem to work OK.
Is there a difference? If yes, what is the difference?

They do both work. I’ve never understood why the :: exists for this
purpose, since the . is the normal way of sending messages to objects
and works perfectly well whether or not the receiver is a class. It’s
on my very short list of things I’d like to see removed from Ruby.

i think it’s quite useful in the context of metaprogramming or classes
or
modules as variables:

m = method_returning_an_module
m::module_method

c = method_returning_an_class
c::class_method

o = method_returning_an_object
o.object_method

i find this approach helps me understand which kind of thing my
variables have
at a quick glance. it’s a similar idea to naming arrays with plural
words

people = []
person = people.first

which some hate and some love. still, these kinds of techniques can
reduce
the need for comments and preserve programmer sanity.

kind regards.

-a


#10

Hi –

On Mon, 27 Mar 2006, removed_email_address@domain.invalid wrote:

i think it’s quite useful in the context of metaprogramming or classes or

i find this approach helps me understand which kind of thing my variables
have
at a quick glance. it’s a similar idea to naming arrays with plural words

people = []
person = people.first

which some hate and some love.

Does anyone hate calling a variable person? :slight_smile:

still, these kinds of techniques can reduce the need for comments
and preserve programmer sanity.

I honestly don’t see any connection between the two techniques (:: and
suggestive variable names). c::meth doesn’t communicate anything to
me about c. Even if it did, I’m not sold on the idea that it’s
necessary to have a different message-sending operator for a
particular class of objects. It doesn’t scale: you can come up with
lots of variable names (my_class, etc.), but you can’t keep adding
operators to make distinctions among receivers. Nor is it necessarily
vital in very many cases to make such distinctions.

And when it’s a matter of String.new vs. String::new, you already know
it’s a class anyway :slight_smile:

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#11

On Mon, 27 Mar 2006 removed_email_address@domain.invalid wrote:

I honestly don’t see any connection between the two techniques (:: and
suggestive variable names). c::meth doesn’t communicate anything to me
about c.

it does though - you know c must be a module (classes being
modules).

Even if it did, I’m not sold on the idea that it’s necessary to have a
different message-sending operator for a particular class of objects. It
doesn’t scale: you can come up with lots of variable names (my_class, etc.),
but you can’t keep adding operators to make distinctions among receivers.
Nor is it necessarily vital in very many cases to make such distinctions.

i can see that point of view. still, i like this:

 harp:~ > cat a.rb
 module A
   module B
     module C
       class D; end
       E = 42
       def self::foo() 42 end
     end
   end
 end

 namespace = A::B::C

 p namespace::D
 p namespace::E
 p namespace::foo


 harp:~ > ruby a.rb
 A::B::C::D
 42
 42

and i think it’s why ‘::’ can call methods - though this is a w.a.g.

And when it’s a matter of String.new vs. String::new, you already know it’s
a class anyway :slight_smile:

only sometimes though:

module M
class C
end
end

def C(*a, &b) ::m::C::new(*a, &b) end

C.new

this is contrived, but String is a perfect example of this: both
String() and
String exist and certainly many libs export ‘const methods’.

all you really when a variable starts with [A-Z] is that it’s a const.
this
happends quite a bit in my code because i always wrap up code into
modules so i
end up with things like this:

module M
module Logging
end
module Util
end
class A
include Util
include Logging
end
class B
include Util
include Logging
end
class C
include Util
include Logging
end
def self::new *a, &b
C::new *a, &b
end
end

where ‘C’ is sort of the ‘default’ or ‘main’ class in this set - so i
provide
a convenience method for the common ctor case. of course you can use
‘.new’
here… i’m just pointing out that a lefthand side const may not be a
class.

regards.

-a


#12

Hi –

On Mon, 27 Mar 2006, removed_email_address@domain.invalid wrote:

On Mon, 27 Mar 2006 removed_email_address@domain.invalid wrote:

I honestly don’t see any connection between the two techniques (:: and
suggestive variable names). c::meth doesn’t communicate anything to me
about c.

it does though - you know c must be a module (classes being modules).

Why?

c = “abc”
c::split(//) # [“a”, “b”, “c”]

module A

and i think it’s why ‘::’ can call methods - though this is a w.a.g.
To each his own. My brain has to parse “namespace::foo” twice: the
first time it says, “Didn’t he mean namespace::Foo?” and the second
time it says, “Oh right, Ruby’s superfluous message-sending operator”
:slight_smile:

i
end
end
end

where ‘C’ is sort of the ‘default’ or ‘main’ class in this set - so i provide
a convenience method for the common ctor case. of course you can use ‘.new’
here… i’m just pointing out that a lefthand side const may not be a class.

Absolutely – indeed, it can be anything. (My String example was
meant to evoke the specific case of a well-know class.) That’s why I
don’t find it informative. I don’t know; I guess I just see the
notion of “sending a message to an object” fully covered, on the
operator side (as opposed to the “send” side), by the dot, and no
clear rationale for Ruby having two such operators.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#13

On Mon, 27 Mar 2006 removed_email_address@domain.invalid wrote:

it does though - you know c must be a module (classes being modules).

Why?

c = “abc”
c::split(//) # [“a”, “b”, “c”]

wow. i never noticed that!

harp:~ > ruby a.rb
A::b::C::smiley:
42
42

and i think it’s why ‘::’ can call methods - though this is a w.a.g.

To each his own. My brain has to parse “namespace::foo” twice: the first
time it says, “Didn’t he mean namespace::Foo?” and the second time it says,
“Oh right, Ruby’s superfluous message-sending operator” :slight_smile:

funny - i guess my old c-- habits are showing through!

Absolutely – indeed, it can be anything. (My String example was meant to
evoke the specific case of a well-know class.) That’s why I don’t find it
informative. I don’t know; I guess I just see the notion of “sending a
message to an object” fully covered, on the operator side (as opposed to the
“send” side), by the dot, and no clear rationale for Ruby having two such
operators.

yeah - i really do see that. i bounce back and forth sometimes. i
guess
there are just cases where, to me, the ‘::’ seems to look better - but
it is
certainly non-essentially and non-orthogonal. fortunately we are not
programming python or all such fluff would be removed! :wink:

regards.

-a