Last Updated:

.NET for Ruby: Methods and Variables

In the last post in our series on migrating from .NET to Ruby, we looked at the . Classes were a very deep topic because there are many class differences between .NET and Ruby. In this post, we'll look at methods and variables. First, we'll look at how to create and call methods, then we'll look at blocks and some of the uses of blocks, and finally, we'll look at the types of variables that exist in Ruby.

As always, we'll actually be comparing Ruby to C# because .NET is a framework, not a .

Methods

The Ruby methods are fairly simple, especially since we don't have to worry about the type system, allowing us to skip defining parameter types and return method types. Methods in ruby are written using the def keyword to trigger the method definition, and they are closed with the end keyword, for example:

def a_method() # this is a Ruby method end

This is very different from the .NET method, which would look like this:

public void AMethod() { // this is a C# method }

When using method parameters, you write them in parentheses and separate them with commas:

def a_method(a, b, c) # this method has three parameters a, b, and c end

As discussed in a previous post about Ruby classes, since Ruby is written using duck utilities, you don't need to declare the data types of your parameters in method definitions. Compare this to .NET:

private void AMethod(int a, int b, int c) { // this method has three parameters: // an integer a, an integer b, and an integer c }

The difference between these two pieces of code is the number of characters that need to be written. Ruby is known as a short language, and definitions of small methods are clearly one of the things that make Ruby so concise.

Moving on, let's look at one of the more obscure Ruby syntaxes. In the code, you can see the methods defined without parentheses – suffocate!

def a_method a, b, c # this method also has three parameters a, b, and c end

This is a perfectly correct syntax, and you can use it in your own code. Let's go back and rewrite our first example using this syntax:

def a_method # No brackets here end

So you can see that Ruby methods are significantly different from .NET. But before you release a few cowboy coders, it's important to tell you about the accepted community practice, namely that when defining methods, omit parentheses for methods without parameters and use parentheses when your methods have parameters.

Let's move on to method calls. They look just like .NET method calls, and you can also execute them without parentheses:

AMethod(1, 2, 3);
a_method(1, 2, 3) a_method 1, 2, 3

All of the above lines of code call a_method with arguments 1, 2, and 3.

Now that we're done with creating and calling methods, let's look at some interesting aspects of methods that lack C# and where Ruby shines.

Blocks

Let's start with the blocks. Blocks are defined using curly braces or between the do and end keywords:

 

{ puts "A Block" }
do puts "also a block" end

Conceptually, blocks are similar to lambda expressions in C#, and you can pass them to a method and then execute them from the context of that method. This is done using yield:

def a_method puts "begin" yield puts "end" end a_method { puts "block code" }

What are the conclusions:

begin block code end

And just like methods, blocks can accept variables in them. This is done by using a channel character to separate the variable name as follows:

def a_method yield("George") end a_method { |name| puts name } #=> George

The equivalent code in C# would look like this:

public static void a_method(Action<string> block) { block("George"); } a_method((name) => System.Console.WriteLine(name));

Blocks are actively used in Ruby, and they allow us to implement some useful functions, such as the C# usage operator. For example, here is some code to write to a C# file:

using (StreamWriter file = new StreamWriter(@"Output.txt")) { file.WriteLine("Line 1"); }

This code opens the Output.txt file, then writes output.txt 1n to it, and finally closes the file handle. Ruby is capable of the same thing, but instead uses blocks to do the same:

File.open("Output.txt", "w") do |file| file.write "Line 1" end

Pretty neat, isn't it? In the above code, file is a variable reference to the IO object created by File.open. I'll admit that Ruby's block syntax is a bit more mysterious than C# syntax, since in C# you need to clearly state what you're using. This will be a small obstacle for you when learning Ruby.

There are many more powerful applications for blocks. Take Sinatra, for example. Sinatra uses blocks to create a DSL (Domain Specific Language) for its URL routing. Hello, the world of Sinatra! An example looks like this:

get '/hello' do 'hello world' end

In the example above, get is simply a method call with a block attached to its end. This makes the routes very easy to write in Sinatra and makes the code very easy to read while remaining expressive in its functionality. RubySource has a four-part series about Sinatra that's also worth a look!

Ultimately, blocks are just an implementation of the strategy pattern built into the Ruby language. And because blocks are so easy to write, they are widely used when Rubyists write their code.

Variables

Moving on from blocks, let's focus the rest of this post on the most basic element of a Ruby program, a variable. Local variables are variables that you write in your Ruby methods, which are written as follows:

a_variable = 2

Equivalent code in C#:

var a_variable = 2;

Again, there's no need to tell Ruby what type of variable you have. Ruby understands this on its own, which makes the variable syntax as concise as the method syntax. Ruby variables use a naming convention called the snake register. Therefore, instead of using capital letters, as in .NET, to distinguish between words in a variable, you should use an underscore. The variables below are valid variable names:

variable a_variable a_really_big_variable_name

The variables below are still valid Ruby variables, but they violate the Ruby naming convention, so they should not be used.

Variable A_Variable areallybigvariablename

When writing classes in Ruby, there are several special notations to distinguish between local variables and instance variables. Instance variables begin with the at: @ symbol. This is significantly different from .NET, so it's worth comparing the two:

public class Example { private int iv; public Example() { iv = 12; } }
class Example def initialize @iv = 12 end end

In both of the class examples above, an iv instance variable is created in each Example instance. In Ruby, there is no explicit declaration of a variable @iv, instead, by writing a 12 assignment to @iv Ruby is smart enough to determine that @iv is your instance variable.

In addition to instance variables, Ruby has another type of variable known as class variables. For those of you who come from the world of .NET, this is the same as a static variable. To create a class variable, you use a double character: @@ . The following code examples are equivalent:

public class Example { private static int id = 42; public static int GetId() { return id; } }
class Example @@id = 12 def self.get_id @@id end end

It's also worth noting that Ruby also has global variables. They start with a dollar sign: $ . You're unlikely to encounter global variables when you start learning Ruby, so I won't list existing variables, however, the Ruby User Guide does have a list of global variables.

And that's where we'll bring this post to an end. By the end of this post, you'll be able to create methods, call methods, use blocks, and know about 3 types of variables in Ruby. For now, if you've been following this series, you have the basic building blocks for starting writing your own Ruby programs. You have an environment to work with, classes to work with, and now methods and variables to build your routines.