Thursday, May 31, 2012

What are ruby modules and how do they work?

A ruby module is basically a container for constants and methods. It is sort of a mix between structures in languages like C and C++ and interfaces in Java (because it can be mixed in to simulate multiple inheritance - more on that later). Using a ruby module works very well for resolving namespace conflicts and promoting a well abstracted program design.

To define a ruby module, you type module MyModule. Modules must begin with an uppercase letter, I believe. Just as with a class, you end the module definition with the end keyword. Inside a module, you can define constants (which must also start with a capital letter) and functions with the def statement. An important note: you can define constants in MyModule by just writing CONSTANT = 5 or the like, but you must define methods by prefixing their names with the module name and a dot as in MyModule.function.

When you have defined a module, you can access its constants with the :: operator as in MyModule::CONSTANT and its functions with MyModule.function (the . operator). Here's a full example (with albeit stupid outputs):

module OneThing
VALUE = 24
def OneThing.function
puts 'this is the first thing'
end
end
module TwoThing
VALUE = 25
def TwoThing.function
puts 'this is the second thing'
end
end

puts OneThing::VALUE.to_s
OneThing.function

puts TwoThing::VALUE.to_s
TwoThing.function

This will output:

24
this is the first thing
25
this is the second thing

So that's how modules work in ruby. More on mixing in modules later when we talk about inheritance and multiple inheritance.

Sunday, May 27, 2012

How do you work with public and private in ruby?

In ruby, there are three levels of privacy that class methods can have. Public methods of a class can be called on any object of that class; protected methods can be called form inside the class definitions of the class or classes that extend it; private methods can only be called form inside the class which defines them (they can only be called on the implicit object self).

The simplest way to define levels of privacy for a method is to put the public, protected, or private keyword before it, as such:

private
  def private_method
    puts 'a public method called this private method'
  end

Note that you do NOT need to specify an end statement to correspond to the private statement: any method defined after the private statement will be private unless otherwise specified with another permissions modifier statement.

You can also pass symbol arguments to the private, public and protected functions to make the corresponding methods private, public or protected. For example,

def private_method
  puts 'a public method called this private method'
end
private :private_method

would produce the same result as the previous example. For me, it's much easier to call the private function with a symbol after the function definition. That was a function definition is sort of in two parts: the actual logic and the permission setting. Here's a test file that demonstrates private, protected, and public methods:

class PrivateTest
def initialize
@size = 5
end
def this_is_private x
'this should be private '+x
end
private :this_is_private

def this_is_public x
this_is_private x
end

def private_again
puts 'hello, a private method was called'
end
private :private_again

def protected_method
puts 'mustve been called from a class or subclass'
end
protected :protected_method

def call_protected
protected_method
end
def is_it_public?
puts 'yep its public'
end
end

class ProtectedTest < PrivateTest
end

puts 'commencing tests'
pvt = PrivateTest.new
ptc = ProtectedTest.new

# pvt.this_is_private
pvt.this_is_public 'hello' #works
# pvt.private_again
# pvt.protected_method
pvt.call_protected
pvt.is_it_public?

# ptc.this_is_private
ptc.this_is_public 'hello'
# ptc.private_again
# ptc.protected_method
ptc.call_protected
ptc.is_it_public?

puts 'all passed.'

The commented out tests cause an error, but the uncommented tests run without error. As far as I can tell, there is no way to have protected static variables.

So that's how public and private work in ruby.

Friday, May 25, 2012

How do you define classes in ruby?

To define a class in ruby, you simply have to type class MyClass. The naming convention of capitalizing class names is enforced in ruby, so you have to start class names with a capital letter. The class definition is terminated by and end statement.


The constructor of every class in ruby is called initialize. You can define a constructor by simply defining a function with that name, and any arguments you pass to MyClass.new will be passed to initialize. You do not have to specify a constructor if you don't want to; ruby will create one with no parameters that does nothing if you like. In this case, every field will initially be nil, if you try to access it.


Object fields in ruby are denoted by the enforced convention of the @ sign. For example, saying


class DListNode
  def initialize
    @item = 5
  end
end


will, on the creation of a new DListNode object, set the object's size field to 5. You can define methods just as you defined the constructor, although obviously methods can have any name you like. Except they can't start with a capital letter. Or @.


Ruby has a very cool convention for writing functions to access object fields. There are three built in functions called attribute_accessor, attribute_reader and attribute_writer, which each take in a variable number of symbols and set permissions accordingly. For example, if you wanted to have the size of a DList (doubly linked list data structure) be accessible to any program that wanted to read it, but keep programs from changing it, you would say attribute_reader :size, conventionally before you define initialize. This means that some other program would be able to say my_dlist.size and it would return the correct value, but it would not be able to say my_dlist.size = 6.


If you wanted to make the size field totally public, you could say attribute_accessor :size instead, which would allow other programs to change my_dlist.size. If for some reason (I can't think of any at the moment) you only wanted other programs to have write access, you could say attribute_writer :size.


Note that this means, if you specified attribute_reader for a field, you do not have to refer to it with the @ prefix later on. However, if you did not specify read access, you still need to say @size, instead of just size. This is because, I believe, ruby looks at the object fields first when looking for a value of a name inside a class.


Here's a full (though not fully well encapsulated) implementation of a doubly linked list in ruby for you to look over.




class DListNode
  attr_accessor :item, :nextone, :prevone
  def initialize(item=nil, nextone=nil, prevone=nil)
    @item = item
    @next = nextone
    @prevone = prevone
  end
  def to_s
    if nextone.item == nil
      return item.to_s unless item == nil
      return 'nil'
    end
    return item.to_s + ', ' + nextone.to_s unless item == nil
    return 'nil, ' + nextone.to_s
  end
end


class DList
  attr_reader :size
  def initialize
    @size = 0
    @head = DListNode.new
    @head.nextone = @head
    @head.prevone = @head
  end
  def add item
    node = DListNode.new item
    node.prevone = @head.prevone
    node.nextone = @head
    node.prevone.nextone = node
    node.nextone.prevone = node
    @size += 1
  end
  def to_s
    '['+@head.nextone.to_s+']'
  end
end


So that's how to define classes in ruby.

Wednesday, May 23, 2012

How do you throw and catch exceptions in ruby?

To throw an exception (or Error) in ruby, you simply have to type something along the lines of raise 'you did something wrong' inside a begin and end block. This raises a RuntimeError. If you would like to raise some other error, such as a LocalJumpError or, for example, some other error object that you defined,  you can instead say raise LocalJumpError 'you jumped around and you shouldn't have!'. You can raise an error without a message as in simply raise MyError, or you can even raise a RuntimeError with no message by just typing raise.


To catch an error (to do something when an error happens), you can say rescue. rescue with no arguments will simply catch any error, rescue RuntimeError will catch only RuntimeErrors, and rescure RuntimeError => e will catch only RuntimeErrors and provide you with a reference to the RuntimeError object which was raised, and which you can call methods on as specified in the ruby documentation. For example, e.message would return the string that was passed along with the raise clause.


The allegory to a finally clause in java or python is the ensure statement in ruby. Anything positioned after this statement but before the end of the begin...end block will always be executed, no matter what. Ruby does NOT operate by the same rules as java and python when it comes to returning things inside the begin...end block, and raises a lot of confusing LocalJumpErrors if you try to.


Here's a full example:


def raise_if_string x
  raise RuntimeError, 'you tried to pass a string, didn't you?' unless x.class != String
end


begin
  raise_if_string 5       #will do nothing
  raise_if_string 'hello'   #will throw RuntimeError
rescue RuntimeError => e
  print e.message
ensure
  puts 'this will always be printed. goodbye'
end


The output of this would be:


you tried to pass a string, didn't you?
this will always be printed. goodbye


So that's how you throw and catch exceptions in ruby.

Tuesday, May 22, 2012

What does the & mean in ruby?

The unary ampersand operator converts a block to a proc and a proc to a block. There are some functions, such as Array.map, which expect to be passed a block. You can pass these functions a proc instead with the & operator.


For example, say you have square = lambda {|x| x*x}. You can they write [1,2,3].map(&square), and that will return an array with elements 1, 4, and 9.


Conversely, you can use the & operator to pass a block where a proc would usually be required. Consider this function:


def apply_proc arg, &process
process.call(arg)
end


You can then say apply_proc('hello') {|x| puts x}, and it will work as expected: it will print hello. Important: parentheses are REQUIRED here. If you were just to say apply_proc 'hello' {|x| puts x} or apply_proc 'hello', {|x| puts x}, it would SyntaxError, because ruby would be unable to determine that the block was supposed to be the last argument (which seems to me to be kind of backwards, but that's how it is). Also, you cant have a function definition like def apply_proc &process, arg, because a block can only be passed as the last argument of the function. This also means, or course, that you can only pass one block to a function. If only blocks were first class objects.


One more thing, on how things are actually converted in ruby. When ruby sees an & sign, it checks to see if the operand of the & is a proc, and if it is not, it converts it to a proc before converting it to a block using the .to_proc method. In ruby 1.9, the & operator works with symbols - &:capitalize gives you the string method capitalize. You HAVE to be careful of this, though. :capitalize.to_proc.call('hello') functions exactly the same as 'hello'.capitalize - the symbol to_proc method accepts an argument and calls "itself" on that argument. AND, as if you weren't already confused enough, you CAN'T say &:capitalize.call('hello'), you can only pass a proc to a function with an ampersand notation, as in apply_proc('hello', &:capitalize). This is incredibly confusing and absurd to me, because the symbol is not a block, as it would seem that it should be. But at any rate, ruby is confusing.


So that's what the & means in ruby.

Monday, May 21, 2012

What does the ruby p function do?

The p function takes a variable number of arguments and prints how they would be displayed in the ruby interpreter. This is the same as the string that is returned by the obj.inspect method.

Example: you have an array a = [1,2,3,4] and a string s = 'hello'. a.inspect returns the string [1,2,3,4], and s.inspect returns the string "hello" (including the quotation marks). So p a,s would output:

[1,2,3,4]
"hello"

That's what the ruby p function does.

Sunday, May 20, 2012

What are here docs and how are they implemented in ruby?

A here document is a way to represent a multiline string. It's not a concept that's unique to ruby - it's also used in shell scripts, php, perl, and some other scripting languages. In ruby, regular strings with double or single quotes can span multiple lines, so there is almost never a need for here documents.

Of course, in true ruby style, there is an implementation available. To define a here doc, you type <<ID, where ID is some unique word, like EOF or MY_COOL_LIST. The convention, as I understand it, is to type this identifier in all caps. Then, use as many lines as you want to define the actual string. Ruby will stop defining the string when it encounters the identifier again, on its own line. So for example:

puts <<HEREDOC
Hello there!
This is a heredoc, which means
that       if you print it, line breaks and spacing will be preserved.
HEREDOC

Will print:

Hello there!
This is a heredoc, which means
that       if you print it, line breaks and spacing will be preserved.

A couple things to note: the text does not have to be specifically enclosed in the <<ID and ID; instead, saying <<ID specifies that a heredoc will be defined on the following lines. Also, if there are two heredocs defined on one line, e.g. as in func(<<DOC1, <<DOC2), then the second doc will begin to be defined on the line after the closing DOC1. Then you can treat the <<DOC1 declaration as an object, as in the above example. Example: you can do this (copied from Nicholas Evans on Jay Fields' blog):

array_of_long_pasted_in_strings = [<<FOO, <<BAR, <<BLATZ]
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
FOO
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
BAR
I recently discovered that I can use multiple heredocs as parameters.
Isn't that neat? Because almost nothing needs to be escaped with heredocs, I prefer to use it when strings are pasted in from elsewhere. Because the syntax for using it inside parameter lists is so nice, I prefer to use it whenever a multiline string literal is being passed into something as an argument.
BLATZ

Another quick note: if you use <<ID to define heredocs, then the closing ID must be the first thing on its line, or it will be included in the multiline string. If you put in a dash, like <<-ID, the string definition will end whether there are spaces before the ending ID or not. Refer to the blog post linked above for a good example of this.

So why would you want to use heredocs instead of just regular multiline strings? The only example I can think of is if you have a function with a lof of arguments that you need to pass a multiline string to. For example: open_address(:write, <<ADDRESS, 10. ' '). Then you could define the multiline string below the function call instead of awkwardly making the function call span multiple lines.

So, that's what heredocs are, and that's how they're implemented in ruby.