Previously in Lesson 1 of this Ruby crash course I spoke mainly about getting Ruby setup and some basic differences in the syntax. In this lesson we are going to focus and creating classes and methods in Ruby.

Defining a Method in Ruby

Ruby like PHP is a scripting language. What this means is that you don’t need to create a main run method like you would have to in Java. Instead you simply type your commands and you script will run line by line until it terminates. This allows you define methods of code outside of classes, that can be called globally throughout the script. Lets start right in with a basic example:

def myMethod
    puts "testing"
end

As you can see the def command is used to define methods, with the method name following it. If we wanted to have our method take parameters then we add parenthesis with named variables that can be defaulted to values similarly to PHP, Java, and other programming languages.

def myMethod( param = "value" )
    puts param
end

Calling a Method in Ruby

Now for a bit of oddness. In Ruby you don’t need to add the () parenthesis to a method call instead you simply need to pass the method name. Lets use our previous example to illustrate.

myMethod
 
myMethod()

Both of these commands will cal the method you have created. No offense to anyone but how could typing a method like it was a variable make a language easier to read or understand? It seems to me more that the underlying programmers were lazy and simply decided “I wish I didn’t have to type 2 additional characters to call a method”, Seriously what gives?

Defining an Object

Similar to other programming languages an Object in Ruby is created by use of the class keyword. Similar to a method you specify the name after the keyword and its definition terminates by the end keyword. In a class you then define its variables and methods. Similar to PHP’s __construct methods Ruby defines it’s class constructors with initialize, unlike PHP you can not have your constructor be the same name as the Class’s name. Lets take a look at a sample Class.

class MyClass
    def initialize( user_name, age )
        @user_name = user_name
        @age = age
    end
    def welcome 
        puts "Welcome #{@user_name}"
    end

Looking at the code you may think “Where are the variable definitions?” In Ruby you don’t need to specify variable definitions outside of the initialize method. Instead the use of the @ character before a name defines that variable as an instance variable that will be accessible to all methods of the class. At this point lets just say that Ruby is built on some strong naming conventions that will dictate how you write your code. The second thing you may notice is the use of the #{… } notation, this simply means to output the value of what is inside into the containing string.

Instantiating and utilizing Classes

Now that we have defined our class the next logical step would be to instantiate it and use it in our script. unlike Java and PHP where you use the new command to instantiate an Object, in Ruby the new command is actually a function of the Class. This means that your instantiation of the class would be ClassName.new(params).

obj = MyClass.new( "mdbitz", 26 )

A little different but nothing to cry over. Now that we have our instance of the class we can call it’s methods like normal again remembering that you don’t need to include the parenthesis.

obj.welcome

At this point our user_name and age variables are considered private in that we can not get or set the properties directly. If we want to we have 2 choices we could define getter and setter methods or we could use the attr_accessor keyword that will change it so that we can access the variables directly by its name.

class MyClass
    attr_accessor :user_name
    attr_accessor :age
    def initialize( user_name, age )
        @user_name = user_name
        @age = age
    end
    def welcome 
        puts "Welcome #{@user_name}"
    end

By utilizing attr_accessor the variables can be obtained or set by simply calling their names.

puts obj.age
obj.user_name = "testUser"

Interfaces, Abstraction, and Inheritance

In Ruby there are no definitions for Interfaces or Abstract classes or methods. Not sure why they decided to not include these basic design paradigms, but there you have it they do not exist. As for inheritance you can extend classes when defining your classes by following the syntax class ClassName < BaseClassName

class MyNewClass < MyClass
    def getInfo()
        puts "USER_NAME: #{@user_name}\nAGE: #{@age}"
    end
end

Although this is Part 1 of 3 on Ruby Classes and Methods I think it is time to learn a little bit more about the Naming Conventions in Ruby.

, , , , , , , ,

When working in applications that utilize a lot of variables I often come across interfaces containing nothing but constants. Instead of creating a class containing the constants the developers choose to define them in an interface that can be implemented by a class so that constants don’t need to be qualified to a class in the code. This is so widespread that it has been termed the Constant Interface Antipattern. To ease users into correctly defining and using interfaces Java introduced Static Import in version 1.5.

To help illustrate why people choose to use interfaces to define constants lets have a look at an example. Lets assume we have defined our constants in the following interface MyConstants.

public interface MyConstants {
    public static final String PASS= "pass";
    public static final String FAIL = "fail";
}

To use the constants one would have their class implement the interface:

public class BadConstants implements MyConstants {
    private void outputResults() {
        System.out.println("FAIL Constant is " + FAIL);
        System.out.println("PASS Constant is " + PASS);
    }
}

As can be seen in the example the reason people prefer to use this method is that they do not have to qualify the constant by instead using:

System.out.println("FAIL Constant is " + MyConstants.FAIL);

To make it easier for coders to write good code Java introduced the Static Import feature in 1.5. What this does is allow us developers to import static properties into the current class’s namespace effectively allowing you to not qualify the constants. This is down by use of the import static statement where you can import a single constant or all constants of a class.

import static com.example.MyConstants.PASS;
import static com.example.MyConstants.*;

To put it simply don’t define constants in an interface, instead create them properly in their own classes and if you really don’t want to qualify them then utilize static import to import the constants into your class.

References

, , , ,