Transformation Thursday - C# to Ruby, How do properties work in Ruby

July 31, 2014

I am learning Ruby and thought it would be useful to other .NET developers who are coming to Ruby to understand the differences.

I’ve covered Namespaces, Classes and Methods previously and would like to follow that up with Properties.

Here is some new code to work with this week.

public class Employee
{

    // class level variable shared by all classes
    public static int NumberOfEmployees;
    private static int counter;

    // instance level private variable
    private string name;

    // A read-write instance property: 
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    // A read-only static property: 
    public static int Counter
    {
        get { return counter; }
    }

    // A Constructor: 
    public Employee()
    {
        // Calculate the employee's number:
        counter = ++counter + NumberOfEmployees;
    }
}

First let’s get familiar with what properties are. Properties are a combined aspects of both fields and methods. When writing to a property you will use the following syntax:

someClass.Property = 1;

When reading you will use this syntax:

var variable = someClass.Property;

Now when implementing a class that has properties, your property is one of two code blocks, it is either a get accessor and or a set accessor. When you read or get a property, the get accessor code block is executed and likewise when you write or set the property the set accessor code block is executed. Should you have a property that only has the get accessor it is considered read-only. When a property only has a set accessor it is a write-only property.

Properties are declared in the class by specifying the access modifiers (as we discussed in the post on methods), the type (i.e. whether it is an int, string, bool) and the name of the property.

Properties are a great way to run some logic before gaining access to the field. So taking our code from above here we can see the different parts.

private string name;

// access modfier: public
// type: string
// property name: Name
public string Name 
{
    get { return name; }
    set { name = value; }
}

In this example we see that Name is backed by a private field variable name, it has been made public and returns a string. At this point, I think we have covered enough on the C# side of properties

Let’s see the same implementation in Ruby.

class Employee
	# class level field shared by all variables
	@@number_of_employees = 0
	
	# gives us access to the class level property using Employee.number_of_employees
	def self.number_of_employees
		@@number_of_employees
	end

	# A read instance property: 
	def name
		@name
	end

	# A write instance property: 
	def name=(name)
		@name = name
	end

  # A Constructor: 
  def initialize
  	@@number_of_employees += 1
  end
end

Unlike C#, there is no static keyword in Ruby, and all properties are public unless specified otherwise. A double “@” denotes that this is a class level variable and thus will be shared amongst different instances. Class level variables / properties are exposed by:

@@number_of_employees = 0
	
def self.number_of_employees
	@@number_of_employees
end

A single “@” specifies that this is an instance level variable and thus each class object created will have its version of this property. Ruby does not have a get and set keywords so instead you create you’re get and set accessors by defining the using the following syntax:

# Get accessor
def name
	@name
end

# Set accessor
def name=(name)
	@name = name
end

If you need to access any of these properties in your class, you will include the “@” sign in-front of the variable name

Just like C# has automatic backed variables using:

public string Name { get; set }

Ruby too has this ability:

# Read, Write accessor
attr_accessor :name

# Readonly accessor
attr_reader :name

# Write accessor
attr_writer :name

Both languages have interesting approaches to this problem. As you can see coming from the .NET world this is very different to what we are accustomed to but not rocket science either. I hope this was helpful to you.


Discussion, links, and tweets

My name is Deon Heyns and I am a developer learning things and documenting them in realtime. Python, Ruby, Scala, .NET, and Groovy are all languages I have written code in. I appeared in the New York Post once. I host my code up at GitHub and Bitbucket so have a look at my code, fork it and send those pull requests.

comments powered by Disqus