0

What is the format/syntax followed in the below declaration/definition of a Ruby class? I don't understand the colons (:) used in the class name. What does that indicate?

class ::Chef::Recipe
  include ::Opscode::ChefClient::Helpers
end

This is from here:

I am familiar with the below way of defining a Ruby class:

class ClassName
   CONSTANT = Z
  ....methods...

end

And i know that a constant is called like ClassName::Z, But the above way of declaration is new to me and where do i find docs on declaring a ruby class like so.

OK999
  • 1,353
  • 2
  • 19
  • 39

3 Answers3

6

The initial :: says "even though we might be lexically inside a class or module, define this new class from the top level namespace". When you use it at the start of a constant name, even if you're inside another module or class scope, the constant you're referring to (or creating) is not inside that scope, but is at the top level (these constants can be listed by printing Object.constants)

Note that the text which follows the "<" (for the superclass) can be any expression which returns a Class object (evaluated at compile time). You can even use a function to return the superclass.

cliffordheath
  • 2,536
  • 15
  • 16
  • Could you please elaborate on this: `The initial :: says "even though we might be lexically inside a class or module, define this new class from the top level namespace".` – OK999 Nov 11 '15 at 07:58
  • Came across this https://www.chef.io/blog/2013/09/04/demystifying-common-idioms-in-chef-recipes/ . it says: "In some recipes, you may see ::File used to refer to the Ruby File class. Why isn’t it just “File”? The reason is because Chef has its own classes named File. Specifically, there are resource and provider classes within Chef called File. To avoid ambiguity — ambiguity leads to errors — whenever we want to refer to Ruby’s File class, we use ::File. " Based on your answer and this blog, does ruby have another class call `chef'? – OK999 Nov 11 '15 at 09:10
  • @OK9999 When writing a Chef recipe you're in an instance of `Chef::Recipe` for the DSL along pure ruby code. That's why you need to avoid ambiguity between DSL methods and pure Ruby methods – Tensibai Nov 12 '15 at 08:50
3
module Foo
  class Bar
  end

  class ::Baz
  end
end

defines Foo::Bar and Baz (not Foo::Baz).

It is similar to how directories work: given existence of /foo, and current directory being /,

cd foo
mkdir bar
mkdir /baz

creates /foo/bar and /baz (not /foo/baz).

Amadan
  • 191,408
  • 23
  • 240
  • 301
1

And, here is an example of how constants are looked up:

A = 1

module X
  A = 'hello'

  class Y
    A = [1, 2, 3]

    def show
      p A
      p ::A
    end
  end

end

X::Y.new.show

--output:--
[1, 2, 3]
1
7stud
  • 46,922
  • 14
  • 101
  • 127
  • Can you instantiate a module? i have came across many docs saying a module cannot be instantiated. This is one such link: http://stackoverflow.com/questions/151505/difference-between-a-class-and-a-module Or, is it that, we can instantiate a class which exist inside a module like what you have done. ` X::Y.new.show` ... I can use irb to test your example though – OK999 Nov 11 '15 at 07:56
  • You can't instantiate a module. You can use a module kind of like a singleton class (by directly calling methods it defines), or you can include a module into a class as a mixin (and than instantiate that class). – Amadan Nov 11 '15 at 08:48
  • OK999, `X::Y` is a class, which you can call new() on. Modules can be used as *namespaces*, which is the case here. Namespaces are used so that name clashes don't occur. If some other developer implements a class named Y, he will define it inside his unique namespace name. – 7stud Nov 11 '15 at 08:50