Last Updated:

.NET for Ruby: Types

o far, in these articles about migrating from .NET to Ruby, we've looked at ruby classes, namespaces, documentation, methods, variables, and the Ruby framework. We covered a lot of land. Today, we'll look at the data types that form the basis of the Ruby language.

Although we don't need to explicitly declare variable data types in Ruby, they still exist. Based on the C# background, you will find many of your friends you know: strings, integers, arrays and hashes. In addition, Ruby introduces several new types: ranges and symbols. We'll cover these basic points in this post.

Strings

Strings are a staple of any programming language. In C#, strings are written as follows:

var value = "string"

and Ruby are virtually the same

value = "string"

The Ruby standard library offers many nice features for working with strings. One of my favorite features is how Ruby formats strings. Ruby provides you with the ability to embed your strings using the syntax #{} In C#, the format string will look something like this:

var place = "Rockey Mountains"
var feeling = "happy!"
var result = string.Format("Driving to the {0} makes me {1}", place, feeling);

In Ruby, the same functionality will look like this:

place = "Rockey Mountains"
feeling = "happy!"
result = "Driving to the #{place} makes me #{feeling}"

And that's not even the coolest part; You can place a calculated expression between curly braces, and the calculated result will be embedded in your string. Let's see what's in action:

puts "I am #{32 - (10 / 2)} years old" 
  #=> I am 27 years old

Ruby also offers another line separator in the form of single quotation marks. This separator doesn't offer the same number of lookups as double quotation marks, so it's useful when you need to output control characters like newline characters and the like:

puts 'Reduced substitutionn' #=> Reduced substitutionn
puts "More substitutionn"    #=> More substition

In the second line above, a new line will be added at the end, whereas the first line will simply print n

Before we continue, one important fact should be noted: Ruby strings are not immutable. Now, based on the .NET background, this will seem very strange because for a C# encoder, strings are immutable. Let's take a look at this concept:

s = "string"
puts s.object_id        #=> 2156184600

s.gsub!("ing", "ong")
puts s.object_id        #=> 2156184600

Here we see that the gsub method! actually changes the string instance, especially note that the value changes, but object_id ! in the method signature there is an indicator that the calling method will change the object to which it is called, which is a Ruby convention. This is a big difference from .NET, so make sure it doesn't baffle you.

I could take an entire post on the lines, but that should be enough to wet your whistle; Read the string documents to better understand what features exist.

Whole

The Ruby integer class is very different from C# int. Although they both represent the same primary data type, the ways in which the languages provide this representation are different. For C#, int is called a value type and is a 32-bit fixed-size integer. In Ruby, an integer is a class that packages or manages two other classes associated with numbers: Fixnum and Bignum.

In more detail, Fixnum is used when an integer value can be represented in a machine word minus 1 bit (it depends on the processor), and Bignum is any value outside the Fixnum range. Now it may seem a bit confusing, but luckily Ruby handles all this information, including converting Fixnum to Bignum in a completely transparent way.

 

A useful aspect of integers in Ruby is that they are represented as objects, which means that all integers have a set of methods that can be called on them. Let me demonstrate two of these methods with an example.

Let's take the concept of alternating zebras and use C# and Ruby to create a piece of code that outputs the string "even" or "odd" for the numbers 1 – 10.

for (int i = 0; i < 10; i++) {
    var i_is = (i % 2 == 0) ? "even" : "odd"
    Console.Write(i_is);
}
10.times do |i| 
  i_is = i.even? ? "even" : "odd"
  puts i_is
end

In the example above, the code performs the same tasks, but the Ruby code is more concise without losing meaning. Also, the ruby code shows two of the methods I mentioned, even? and times Check their relevant documentation if the method names don't make sense.

Arrays

Let's look at the array in C#:

var items = new string[] { "item1", "item2", "item3" }

And in Ruby, you can build an array as follows:

items = [ "item1", "item2", "item3" ]

One area where Ruby arrays vary is that they are not strongly typed. That is, you can have an integer, a string, and an object in an array without complainting Ruby. While you generally won't put an integer, string, and object into the same array, it becomes useful when you have different objects that all implement the same method, and duck typing allows you to do something like this:

class ObjectA
  def hello
    "I'm object A"
  end
end
class ObjectB
  def hello
    "I'm object B"
  end
end
class ObjectC
  def hello
    "I'm object C"
  end
end

[ObjectA.new, ObjectB.new, ObjectC.new].each {|obj| puts obj.hello }
#=> "I'm object A"
#=> "I'm object B"
#=> "I'm object C"

Think about it for a second and you'll see how duck printing can actually manifest in Ruby.

The Array class defines many methods that allow you to easily iterate through the array without having to write loops forwhile

Another interesting feature of the Array class is that it has methods that allow the array to be treated as a stack or queue. The stack has pushpop methods AND for the queue it has pushshift methods

Hash

One of the great things about Ruby is that hashes are first-class citizens Their syntax is concise, and they have an extensive set of features provided in the standard library.

In C#, you can create a hash like this:

Hashtable ht = new Hashtable{ {"key", "value"} };

And in Ruby, the hash is as simple as writing this:

ht = { :key => "value" }

Hashes are widely used in Ruby because of their availability. Adding a new key/value is as easy as:

 

ht[:new_key] = "value"

Or let's say you want to iterate through all the key/value pairs, this code would look like this:

social_media = { :twitter => "cool", :facebook => "scary", :google_plus => "meh" }
social_media.each_pair do |key, value|
  puts "#{key} is #{value}"
end

This would result in:

twitter is cool
facebook is scary
google_plus is meh

If the hashes don't seem too useful at this point, just wait. When we talk about symbols, I'll show you one of the reasons hashes are often used.

Changes

Ranges are a fun data type that takes start and end values that make up the interval between those values. Ranges can be constructed with any object that defines a comparison operator and the succ method. For example, we could create a range of numbers, characters, or dates:

(1..10) #=> 1..10
('a'..'z') #=> a..z
(Date.today - 5...Date.today) #=> #<Date: 2011-11-11>...#<Date: 2011-11-16>

You'll notice that the date example above uses three dots ( ..... For ranges, two dots say "use the entire range" and three dots say "eliminate the end value". Ranges won't come up too often, but when they do you need, they are really useful.

Symbols

Characters are another data type not found in C#, but you will find them widely used in Ruby. The closest comparison between C# and Ruby would be to call symbols a mixture of an enumerator and a constant.

Characters are declared by prefixing a word or string with a colon:

:name #=> :name
:"a symbol" #=> :"a symbol"

The second example is rarely, if ever, used. One of the most common uses of symbols is for option hashes, which are commonly found in frameworks like Rails. Here is an example:

def make_link(href, opts = {})
  title = opts[:title] || href

  "<a href="#{href}">#{title}</a>
end

puts make_link("http://www.sitepoint.com", {:title => "How To Be An Awesome Rubyist"})
  #=> <a href="http://www.sitepoint.com">How To Be An Awesome Rubyist</a>

puts make_link("http://www.sitepoint.com")
  #=> <a href="http://www.sitepoint.com">http://www.sitepoint.com</a>

You can see in the code above, we use the :titlemake_link symbol. The main frameworks in Ruby generally use this convention as it cleans up the method interface and makes it easy to add/remove optional parameters. This way you can change the signature of a method (add or remove parameters) without breaking every piece of code that depends on that method.

It's important to pay attention to why you want to use characters over a string in Ruby. One of the main reasons is that a symbol always refers to the same object, whereas each instance of a string is a separate object (remember, Ruby strings are mutable.) Let's see this in practice:

puts :symbol.object_id #=> 442248
puts :symbol.object_id #=> 442248
puts "string".object_id #=> 2156234340
puts "string".object_id #=> 2156197521

Notice how object_id:symbol This supports the concept of mutable strings, discussed in the strings section.

At this point, we've covered a lot of code when comparing C# with Ruby. Today's article is about the differences between Ruby and C# data types. We explored strings, integers, arrays, hashes, ranges, and characters. I think you are ready to take a C# program and convert it to a Ruby program. I would suggest starting with something like FizzBuzz and work your way up from there. The best way to learn a new language is to write programs in that language.