Basic programming question, help please

class Square
  def initialize
    if defined?(@@number_of_squares)
      @@number_of_squares = @@number_of_squares + 1
    else
      @@number_of_squares = 1
    end
  end
  def self.count
    @@number_of_squares
  end
end

a = Square.new #would return 1
b = Square.new #would return 2
puts Square.count #2 would be printed on the screen

···

--------------------------------------------------------------------

My question is: why is the "self" necessary in "def self.count".
I don't understand the logic behind it.

(I know that I can also type "def Square.count" instead of "def
self.count")

Thanks guys!

--
Posted via http://www.ruby-forum.com/.

You want a class method, not an instance method.

class Square
  def count1
    puts "I am instance method"
  end

  def self.count2
    puts "I am class method"
  end
end

sqr = Square.new

sqr.count1 #=> I am instance method
sqr.count2 #=> NoMethodError
Square.count1 #=> NoMethodError
Square.count2 #=> I am class method

···

On Mon, Mar 7, 2011 at 12:39 PM, Kaye Ng <sbstn26@yahoo.com> wrote:

class Square
def initialize
   if defined?(@@number_of_squares)
     @@number_of_squares = @@number_of_squares + 1
   else
     @@number_of_squares = 1
   end
end
def self.count
   @@number_of_squares
end
end

a = Square.new #would return 1
b = Square.new #would return 2
puts Square.count #2 would be printed on the screen

--------------------------------------------------------------------

My question is: why is the "self" necessary in "def self.count".
I don't understand the logic behind it.

(I know that I can also type "def Square.count" instead of "def
self.count")

Thanks guys!

--
Posted via http://www.ruby-forum.com/\.

The class method in Ruby is represented using self.<method name> or <class

.<method name>, A class method is used to modify the class variables(

which has the same value in every object of that class, as you have in your
program @@number_of_squares).

···

On Mon, Mar 7, 2011 at 5:09 PM, Kaye Ng <sbstn26@yahoo.com> wrote:

class Square
def initialize
   if defined?(@@number_of_squares)
     @@number_of_squares = @@number_of_squares + 1
   else
     @@number_of_squares = 1
   end
end
def self.count
   @@number_of_squares
end
end

a = Square.new #would return 1
b = Square.new #would return 2
puts Square.count #2 would be printed on the screen

--------------------------------------------------------------------

My question is: why is the "self" necessary in "def self.count".
I don't understand the logic behind it.

(I know that I can also type "def Square.count" instead of "def
self.count")

Thanks guys!

--
Posted via http://www.ruby-forum.com/\.

If you want to say "Square.count" then you need a class method and that's how you define one.

I don't know if there is an especial advantage in doing it this way, other than it makes more sense when you read the code. (Anyone?)

You could equally have written:

class Square
  def initialize
    if defined?(@@number_of_squares)
      @@number_of_squares = @@number_of_squares + 1
    else
      @@number_of_squares = 1
    end
  end
  def count
    @@number_of_squares
  end
end

a = Square.new
b = Square.new
puts b.count

Kaye Ng wrote in post #985934:

class Square
  def initialize
    if defined?(@@number_of_squares)
      @@number_of_squares = @@number_of_squares + 1
    else
      @@number_of_squares = 1
    end
  end
  def self.count
    @@number_of_squares
  end
end

a = Square.new #would return 1
b = Square.new #would return 2
puts Square.count #2 would be printed on the screen

--------------------------------------------------------------------

My question is: why is the "self" necessary in "def self.count".
I don't understand the logic behind it.

It isn't necessary:

class Square

  def initialize
    if defined?(@@number_of_squares)
      @@number_of_squares = @@number_of_squares + 1
    else
      @@number_of_squares = 1
    end
  end

  def count
    @@number_of_squares
  end

end

a = Square.new
b = Square.new
puts a.count #2

...but the way in which you define the method determines how you can
call the method. You can choose to define a "class method" or an
"instance method". A class method is called using the class, and an
instance method is called using an object/instance of the class. You
have to decide how you want to call the method: with the class or an
instance.

In your case, I would suggest that Square.count makes more sense in
English where if you ask for a.count, it is not really clear what that
means.

(I know that I can also type "def Square.count" instead of "def
self.count")

You can also use a third syntax:

class Square

  def Square.class_meth1
    puts 'class_meth1'
  end

  def self.class_meth2
    puts 'class_meth2'
  end

  class << self
    def class_meth3
      puts 'class_meth3'
    end
  end

end

--output:--
class_meth1
class_meth2
class_meth3

···

--
Posted via http://www.ruby-forum.com/\.

Class methods are methods that are called on a class and instance
methods are methods that are called on an instance of a class. Here is a
an example to give you an idea:

class Doo
  def self.bar
    puts 'class method'
  end

  def baz
    puts 'instance method'
  end
end

Doo.bar # => "class method"
Doo.baz # => NoMethodError: undefined method ‘baz’ for Doo:Class

Doo.new.baz # => instance method
Doo.new.bar # => NoMethodError: undefined method ‘bar’ for
#<Doo:0x1e820>

···

--
Posted via http://www.ruby-forum.com/.

This is only partially correct. A class method is not 'used to modify
class variables'. It can be used to do that but so can many other mechanisms
including code in an instance method, a block, or a module or class definition.

It is misleading to say a class variable has 'the same value in every object
of the class' since it suggests that class variables are in some way associated
with instances (or 'self') but they aren't. They are associated with the innermost
lexical scope, which for most instance method definitions is just the class
definition block but that is more coincidence than design. Consider the code
below where an instance method for A is defined within the lexical scope of B.

class A
  @@a = "defined in A"
end

class B
  @@a = "defined in B"
  A.send(:define_method, :show_a) { @@a }
  A.send(:define_method, :show_x) { @@x }
end

class C < A
end

A.new.show_a # "defined in B"

class Object
  @@x = 'defined in Object'
end
A.new.show_x # defined in Object"

This shows that the resolution of class variables is based on the lexical
scope and not the dynamic scope. The method #show_x also shows that
the class hierarchy is also traversed when resolving a class variable (first B
is considered and then Object because B is a subclass of Object)

Gary Wright

···

On Mar 7, 2011, at 7:03 AM, Mayank Kohaley wrote:

The class method in Ruby is represented using self.<method name> or <class
>.<method name>, A class method is used to modify the class variables(
which has the same value in every object of that class, as you have in your
program @@number_of_squares).

7stud -- wrote in post #986057:

class Square

  def Square.class_meth1
    puts 'class_meth1'
  end

  def self.class_meth2
    puts 'class_meth2'
  end

  class << self
    def class_meth3
      puts 'class_meth3'
    end
  end

end

--output:--
class_meth1
class_meth2
class_meth3

Whoops. That output is from the following method calls:

Square.class_meth1
Square.class_meth2
Square.class_meth3

···

--
Posted via http://www.ruby-forum.com/\.

Interestingly, if you put

@@x = "defined in B"

in class B, A.new.show_x still shows "defined in Object".

···

On Mon, Mar 7, 2011 at 5:31 PM, Gary Wright <gwtmp01@mac.com> wrote:

On Mar 7, 2011, at 7:03 AM, Mayank Kohaley wrote:

The class method in Ruby is represented using self.<method name> or <class
>.<method name>, A class method is used to modify the class variables(
which has the same value in every object of that class, as you have in your
program @@number_of_squares).

This is only partially correct. A class method is not 'used to modify
class variables'. It can be used to do that but so can many other mechanisms
including code in an instance method, a block, or a module or class definition.

It is misleading to say a class variable has 'the same value in every object
of the class' since it suggests that class variables are in some way associated
with instances (or 'self') but they aren't. They are associated with the innermost
lexical scope, which for most instance method definitions is just the class
definition block but that is more coincidence than design. Consider the code
below where an instance method for A is defined within the lexical scope of B.

class A
@@a = "defined in A"
end

class B
@@a = "defined in B"
A.send(:define_method, :show_a) { @@a }
A.send(:define_method, :show_x) { @@x }
end

class C < A
end

A.new.show_a # "defined in B"

class Object
@@x = 'defined in Object'
end
A.new.show_x # defined in Object"

This shows that the resolution of class variables is based on the lexical
scope and not the dynamic scope. The method #show_x also shows that
the class hierarchy is also traversed when resolving a class variable (first B
is considered and then Object because B is a subclass of Object)

After putting @@x = "defined in B" in class B it shows "defined in B" and
not "defined in Object", and it makes sense as it works according to lexical
scope and not the dynamic scope. This is how I changed the class B without
changing anything else

class B
@@a = "defined in B"
@@x = "defined in B"
A.send(:define_method, :show_a) { puts @@a }
A.send(:define_method, :show_x) { puts @@x }
end

···

On Tue, Mar 8, 2011 at 10:01 AM, Eric Christopherson < echristopherson@gmail.com> wrote:

On Mon, Mar 7, 2011 at 5:31 PM, Gary Wright <gwtmp01@mac.com> wrote:
>
> On Mar 7, 2011, at 7:03 AM, Mayank Kohaley wrote:
>
>> The class method in Ruby is represented using self.<method name> or
<class
>> >.<method name>, A class method is used to modify the class
variables(
>> which has the same value in every object of that class, as you have in
your
>> program @@number_of_squares).
>
> This is only partially correct. A class method is not 'used to modify
> class variables'. It can be used to do that but so can many other
mechanisms
> including code in an instance method, a block, or a module or class
definition.
>
> It is misleading to say a class variable has 'the same value in every
object
> of the class' since it suggests that class variables are in some way
associated
> with instances (or 'self') but they aren't. They are associated with the
innermost
> lexical scope, which for most instance method definitions is just the
class
> definition block but that is more coincidence than design. Consider the
code
> below where an instance method for A is defined within the lexical scope
of B.
>
> class A
> @@a = "defined in A"
> end
>
> class B
> @@a = "defined in B"
> A.send(:define_method, :show_a) { @@a }
> A.send(:define_method, :show_x) { @@x }
> end
>
> class C < A
> end
>
> A.new.show_a # "defined in B"
>
> class Object
> @@x = 'defined in Object'
> end
> A.new.show_x # defined in Object"
>
> This shows that the resolution of class variables is based on the lexical
> scope and not the dynamic scope. The method #show_x also shows that
> the class hierarchy is also traversed when resolving a class variable
(first B
> is considered and then Object because B is a subclass of Object)

Interestingly, if you put

@@x = "defined in B"

in class B, A.new.show_x still shows "defined in Object".

You have to be very careful here if you are experimenting in irb, for example.

Because class variables are actually unique within an entire subtree of the inheritance hierarchy the order and location in which the variable is defined is important.

If you ran my sample code in irb you would have defined '@@x' in Object and effectively made it impossible to define any other '@@x' in any subclass of Object since the pre-existing '@@x' in Object would resolve for every subclass (because Object is the top of the hierarchy).

On the other hand if you created '@@x' in B first then you could create another '@@x' in Object and they would be two different variables. The '@@x' in B would resolve for B and any of its descendants and the '@@x' in Object would resolve for Object and any of its descendants *except* for the subtree with B as its root.

If you think this is complicated and somewhat confusing you are right. Most programmers expect Ruby's class variables to behave like C++'s or Java's class variables but they are very different.

Gary Wright

···

On Mar 7, 2011, at 11:31 PM, Eric Christopherson wrote:

On Mon, Mar 7, 2011 at 5:31 PM, Gary Wright <gwtmp01@mac.com> wrote:

class A
@@a = "defined in A"
end

class B
@@a = "defined in B"
A.send(:define_method, :show_a) { @@a }
A.send(:define_method, :show_x) { @@x }
end

class C < A
end

A.new.show_a # "defined in B"

class Object
@@x = 'defined in Object'
end
A.new.show_x # defined in Object"

This shows that the resolution of class variables is based on the lexical
scope and not the dynamic scope. The method #show_x also shows that
the class hierarchy is also traversed when resolving a class variable (first B
is considered and then Object because B is a subclass of Object)

Interestingly, if you put

@@x = "defined in B"

in class B, A.new.show_x still shows "defined in Object".

See my reply to Eric Christopherson's post for an explanation.

Gary Wright

···

On Mar 8, 2011, at 12:14 AM, Mayank Kohaley wrote:

After putting @@x = "defined in B" in class B it shows "defined in B" and
not "defined in Object", and it makes sense as it works according to lexical
scope and not the dynamic scope. This is how I changed the class B without
changing anything else

class B
@@a = "defined in B"
@@x = "defined in B"
A.send(:define_method, :show_a) { puts @@a }
A.send(:define_method, :show_x) { puts @@x }
end

I am very new to Ruby and coming from C++ background, the class variables
act differently in Ruby vs C++ , Thanks for the explanation Gary

···

On Tue, Mar 8, 2011 at 11:13 AM, Gary Wright <gwtmp01@mac.com> wrote:

On Mar 7, 2011, at 11:31 PM, Eric Christopherson wrote:

> On Mon, Mar 7, 2011 at 5:31 PM, Gary Wright <gwtmp01@mac.com> wrote:
>>
>> class A
>> @@a = "defined in A"
>> end
>>
>> class B
>> @@a = "defined in B"
>> A.send(:define_method, :show_a) { @@a }
>> A.send(:define_method, :show_x) { @@x }
>> end
>>
>> class C < A
>> end
>>
>> A.new.show_a # "defined in B"
>>
>> class Object
>> @@x = 'defined in Object'
>> end
>> A.new.show_x # defined in Object"
>>
>> This shows that the resolution of class variables is based on the
lexical
>> scope and not the dynamic scope. The method #show_x also shows that
>> the class hierarchy is also traversed when resolving a class variable
(first B
>> is considered and then Object because B is a subclass of Object)
>
> Interestingly, if you put
>
> @@x = "defined in B"
>
> in class B, A.new.show_x still shows "defined in Object".
>

You have to be very careful here if you are experimenting in irb, for
example.

Because class variables are actually unique within an entire subtree of the
inheritance hierarchy the order and location in which the variable is
defined is important.

If you ran my sample code in irb you would have defined '@@x' in Object and
effectively made it impossible to define any other '@@x' in any subclass of
Object since the pre-existing '@@x' in Object would resolve for every
subclass (because Object is the top of the hierarchy).

On the other hand if you created '@@x' in B first then you could create
another '@@x' in Object and they would be two different variables. The
'@@x' in B would resolve for B and any of its descendants and the '@@x' in
Object would resolve for Object and any of its descendants *except* for the
subtree with B as its root.

If you think this is complicated and somewhat confusing you are right. Most
programmers expect Ruby's class variables to behave like C++'s or Java's
class variables but they are very different.

Gary Wright

Ohhh, fun. It turns out that Ruby 1.8 shows both as "defined in B",
but Ruby 1.9 has show_x print "defined in Object".

···

On Mon, Mar 7, 2011 at 11:14 PM, Mayank Kohaley <mayank.kohaley@gmail.com> wrote:

On Tue, Mar 8, 2011 at 10:01 AM, Eric Christopherson < > echristopherson@gmail.com> wrote:

On Mon, Mar 7, 2011 at 5:31 PM, Gary Wright <gwtmp01@mac.com> wrote:
>
> On Mar 7, 2011, at 7:03 AM, Mayank Kohaley wrote:
>
>> The class method in Ruby is represented using self.<method name> or
<class
>> >.<method name>, A class method is used to modify the class
variables(
>> which has the same value in every object of that class, as you have in
your
>> program @@number_of_squares).
>
> This is only partially correct. A class method is not 'used to modify
> class variables'. It can be used to do that but so can many other
mechanisms
> including code in an instance method, a block, or a module or class
definition.
>
> It is misleading to say a class variable has 'the same value in every
object
> of the class' since it suggests that class variables are in some way
associated
> with instances (or 'self') but they aren't. They are associated with the
innermost
> lexical scope, which for most instance method definitions is just the
class
> definition block but that is more coincidence than design. Consider the
code
> below where an instance method for A is defined within the lexical scope
of B.
>
> class A
> @@a = "defined in A"
> end
>
> class B
> @@a = "defined in B"
> A.send(:define_method, :show_a) { @@a }
> A.send(:define_method, :show_x) { @@x }
> end
>
> class C < A
> end
>
> A.new.show_a # "defined in B"
>
> class Object
> @@x = 'defined in Object'
> end
> A.new.show_x # defined in Object"
>
> This shows that the resolution of class variables is based on the lexical
> scope and not the dynamic scope. The method #show_x also shows that
> the class hierarchy is also traversed when resolving a class variable
(first B
> is considered and then Object because B is a subclass of Object)

Interestingly, if you put

@@x = "defined in B"

in class B, A.new.show_x still shows "defined in Object".

After putting @@x = "defined in B" in class B it shows "defined in B" and
not "defined in Object", and it makes sense as it works according to lexical
scope and not the dynamic scope. This is how I changed the class B without
changing anything else

class B
@@a = "defined in B"
@@x = "defined in B"
A.send(:define_method, :show_a) { puts @@a }
A.send(:define_method, :show_x) { puts @@x }
end

I probably should have added that a 'class instance variable' in Ruby is analogous to a 'class variable' in C++ or Java. A 'class instance variable' is just a plain old instance variable for an object that happens to be a class.
  
Unfortunately most Ruby books choose to spend more time talking about Ruby's 'class variables' rather than 'class instance variables' and fail to make it clear that Ruby's 'class variables' aren't at all like class variables in other languages. The fact that Ruby's instance variables and class variables have similar sigils just adds to the confusion ('@foo' vs. '@@foo').

Gary Wright

···

On Mar 8, 2011, at 1:10 AM, Mayank Kohaley wrote:

On Tue, Mar 8, 2011 at 11:13 AM, Gary Wright <gwtmp01@mac.com> wrote:

If you think this is complicated and somewhat confusing you are right. Most
programmers expect Ruby's class variables to behave like C++'s or Java's
class variables but they are very different.

I am very new to Ruby and coming from C++ background, the class variables
act differently in Ruby vs C++ , Thanks for the explanation Gary

Mayank K. wrote in post #986119:

I am very new to Ruby and coming from C++ background, the class
variables
act differently in Ruby vs C++ , Thanks for the explanation Gary

Then here's a tip: some experts think class variables should be
unceremoniously eliminated from the language, and that you should favor
"class instance variables" in any case.

Here is an example of a class instance variable:

class ABC
  @x = 10

  def self.get_at_x #class method
    @x
  end

  def get_at_x #instance method
    @x
  end

end

puts ABC.get_at_x

obj = ABC.new
puts obj.get_at_x

--output:--
10
nil

Instance variables are attached to whatever object is self at the time,
self is equal to the class when you are inside a class definition and
outside of any def block, so @x gets attached to ABC. As the output
demonstrates, class instance variables cannot be accessed using an
object of the class.

In addition, class instance variables are *not* inherited while class
variables are inherited:

class ABC
  @x = 10

  @@greeting = 'hello'

  def self.get_at_x #class method
    @x
  end

end

class XYZ < ABC

   def get_class_var
      puts @@greeting
   end

end

xyz_obj = XYZ.new
xyz_obj.get_class_var

puts XYZ.get_at_x

--output:--
hello
nil

···

--
Posted via http://www.ruby-forum.com/\.

Those version are known to have some quarks like that. However, one guy did
mention that it depends the hierarchy or which one u entered first. I
signed up for the wednesday Ruby conference as well for an additional 75
dollars. The author of this book is going to go over improving ruby code
and test driven development. I thought the TDD would be especially helpful.

···

On Wed, Mar 9, 2011 at 8:56 PM, Eric Christopherson < echristopherson@gmail.com> wrote:

On Mon, Mar 7, 2011 at 11:14 PM, Mayank Kohaley > <mayank.kohaley@gmail.com> wrote:
> On Tue, Mar 8, 2011 at 10:01 AM, Eric Christopherson < > > echristopherson@gmail.com> wrote:
>
>> On Mon, Mar 7, 2011 at 5:31 PM, Gary Wright <gwtmp01@mac.com> wrote:
>> >
>> > On Mar 7, 2011, at 7:03 AM, Mayank Kohaley wrote:
>> >
>> >> The class method in Ruby is represented using self.<method name> or
>> <class
>> >> >.<method name>, A class method is used to modify the class
>> variables(
>> >> which has the same value in every object of that class, as you have
in
>> your
>> >> program @@number_of_squares).
>> >
>> > This is only partially correct. A class method is not 'used to modify
>> > class variables'. It can be used to do that but so can many other
>> mechanisms
>> > including code in an instance method, a block, or a module or class
>> definition.
>> >
>> > It is misleading to say a class variable has 'the same value in every
>> object
>> > of the class' since it suggests that class variables are in some way
>> associated
>> > with instances (or 'self') but they aren't. They are associated with
the
>> innermost
>> > lexical scope, which for most instance method definitions is just the
>> class
>> > definition block but that is more coincidence than design. Consider
the
>> code
>> > below where an instance method for A is defined within the lexical
scope
>> of B.
>> >
>> > class A
>> > @@a = "defined in A"
>> > end
>> >
>> > class B
>> > @@a = "defined in B"
>> > A.send(:define_method, :show_a) { @@a }
>> > A.send(:define_method, :show_x) { @@x }
>> > end
>> >
>> > class C < A
>> > end
>> >
>> > A.new.show_a # "defined in B"
>> >
>> > class Object
>> > @@x = 'defined in Object'
>> > end
>> > A.new.show_x # defined in Object"
>> >
>> > This shows that the resolution of class variables is based on the
lexical
>> > scope and not the dynamic scope. The method #show_x also shows that
>> > the class hierarchy is also traversed when resolving a class variable
>> (first B
>> > is considered and then Object because B is a subclass of Object)
>>
>> Interestingly, if you put
>>
>> @@x = "defined in B"
>>
>> in class B, A.new.show_x still shows "defined in Object".
>>
>>
> After putting @@x = "defined in B" in class B it shows "defined in B" and
> not "defined in Object", and it makes sense as it works according to
lexical
> scope and not the dynamic scope. This is how I changed the class B
without
> changing anything else
>
> class B
> @@a = "defined in B"
> @@x = "defined in B"
> A.send(:define_method, :show_a) { puts @@a }
> A.send(:define_method, :show_x) { puts @@x }
> end
>

Ohhh, fun. It turns out that Ruby 1.8 shows both as "defined in B",
but Ruby 1.9 has show_x print "defined in Object".