-1

I have written down a sample program and I don't understand the following:

  1. Why constructor without any arguments are not called in Ruby?
  2. How do we access the class variable outside the class's definition?
  3. Why does it always append newline characters at the end of the string? How do we strip it?

Code:

class Employee
    attr_reader :empid
    attr_writer :empid
    attr_writer :name
    def name
        return @name.upcase
    end
    attr_accessor :salary
    @@employeeCount = 0
    def initiaze()
        @@employeeCount += 1
        puts ("Initialize called!")
    end
    def getCount
        return @@employeeCount
    end
end

anEmp = Employee.new
print ("Enter new employee name: ")
anEmp.name = gets()
print ("Enter #{anEmp.name}'s employee ID: ")
anEmp.empid = gets()
print ("Enter salary for #{anEmp.name}: ")
anEmp.salary = gets()
theEmpName = anEmp.name.split.join("\n")
theEmpID = anEmp.empid.split.join("\n")
theEmpSalary = anEmp.salary.split.join("\n")
anEmp = Employee.new()
anEmp = Employee.new()
theCount = anEmp.getCount
puts ("New employee #{theEmpName} with employee ID #{theEmpID} has been enrolled, welcome to hell! You have been paid as low as $ #{theEmpSalary}")
puts ("Total number of employees created = #{theCount}")

Output:

Enter new employee name: Lionel Messi
Enter LIONEL MESSI
's employee ID: 10
Enter salary for LIONEL MESSI
: 10000000
New employee LIONEL
MESSI with employee ID 10 has been enrolled, welcome to hell! You have been paid as low as $ 10000000
Total number of employees created = 0
Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
Raj Pawan Gumdal
  • 7,390
  • 10
  • 60
  • 92
  • 1
    You're using "puts", which appends a newline. – Dave Newton Mar 18 '12 at 17:59
  • In answer to #2, you probably want to define the getCount as a class method, not an instance method. You'd then call Employee.getCount, rather than calling getCount on an instance. – Marc Talbot Mar 18 '12 at 18:04
  • Yes, that can be done, but I was trying to access Employee.@@employeeCount which used to throw error. Is this wrong way of accessing a static variable? – Raj Pawan Gumdal Mar 18 '12 at 18:09
  • Yes. Have you considered reading some Ruby docs/tutorials? Searching for this provides answers. – Dave Newton Mar 18 '12 at 18:19
  • 1
    @Raj "Static" is not a valid term in Ruby, variables that begin with `@@` are called *class variables*. – Andrew Marshall Mar 18 '12 at 18:22
  • Yes @DaveNewton I always do my homework before posting here (well couldnt easily makeout my mistake in the first question though :P) I have checked in Ruby documents with me, none of them speak about directly accessing the class variables, neither about stripping. I googled for a while without success. – Raj Pawan Gumdal Mar 18 '12 at 18:23
  • 1
    @Raj Searching for "ruby static variables": [SO answer](http://stackoverflow.com/questions/2416372/static-variables-in-ruby), searching for "ruby class variables": [SO answer](http://stackoverflow.com/questions/2084490/ruby-class-variables). Not sure how those didn't show up for you. – Dave Newton Mar 18 '12 at 18:35

3 Answers3

1

The newlines are from the user input. When the user types something and terminates the input with a newline (enter key) the newline is seen as part of the input. You can strip it off with the String#strip() method:

empName = empName.strip

or use the in-place method:

empName.strip!

To retrieve the value of the class variable you need a static getter (note the self.):

def self.getCount
    return @@employeeCount
end

Alternatively you can you the class_variable_get method.

Tomas Markauskas
  • 11,496
  • 2
  • 33
  • 35
  • Looks like 'class_variable_get' is a private method and Ruby doesnt respond to it. But yes, static method is an option, though I was still curious of how to access the class variables directly. – Raj Pawan Gumdal Mar 18 '12 at 18:18
  • I get this: 'private method `class_variable_get' called for Employee:Class (NoMethodError)' – Raj Pawan Gumdal Mar 18 '12 at 18:19
  • You have to call it like this: `Employee.class_variable_get(:@@employeeCount)` (it just worked for me) – Tomas Markauskas Mar 18 '12 at 18:28
  • I did the same and still getting the error. Looks like it is deprecated in higher versions of Ruby. I am using ruby-1.9.3-p125 version. – Raj Pawan Gumdal Mar 18 '12 at 18:31
  • 1
    `$ irb irb(main):001:0> RUBY_DESCRIPTION => "ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-linux]" irb(main):002:0> class Employee; @@employeeCount = 42; end => 42 irb(main):003:0> Employee.class_variable_get(:@@employeeCount) => 42 ` – dbenhur Mar 18 '12 at 22:52
1

For Question 1: Why constructor without any arguments are not called in Ruby?

You wrote def initiaze(). Correct would be def initialize():

def initialize()
    @@employeeCount += 1
    puts ("Initialize called!")
end
knut
  • 27,320
  • 6
  • 84
  • 112
0
  1. as you seem to have noticed you misspelled initialize when defining the method
  2. you can't reference the class variable directly outside the class, but you can make class or instance accessors for it, or use Module#class_variable_get: Employee.class_variable_get(:@@employeeCount)
  3. gets returns the whole line the user inputs, including the terminating newline. Another answer recommended String#strip but this removes all trailing and leading whitespace. If you just want to remove the newline, use String#chomp, empName = empName.chomp! Be careful if you're tempted to apply chomp directly to gets as gets will return nil at end of file and you'll raise NoMethodError sending :chomp to nil

BTW, your camelCasedNames are not good ruby style. Constants should be all UPPER_CASE, except class and module names which should be CamelCased with leading cap, all other names should be lower_case_with_underscores_to_separate_words. Also, in ruby, one generally omits the empty parens on argumentless method calls and definitions.

dbenhur
  • 20,008
  • 4
  • 48
  • 45