Saturday, May 19, 2012

What is the equivalent of a lambda function in ruby and how is it used?

In python, you can define a lambda function with funct = lambda x: x*x, and from then on funct will be a callable function that takes one argument and returns the square of the argument. In ruby, the equivalent system is called a Proc (procedure) object.

A proc is basically just an object that takes a block at its instantiation. For example, you could say funct = Proc.new {|x| x*x}, and then funct would be a proc object equivalent to the python example above. Proc objects CANNOT be called like regular functions, however: you can't say puts funct(4), or anything like that. You CAN, however, invoke the block of the proc object with funct[4] (straight brackets) or by calling the call method: funct.call(6).

There are a couple of other notations for instantiating proc objects. If you say proc {block}, it's the exact same thing as saying Proc.new {block}. You can also say lambda {block}, which will give you almost the same proc object.

Interestingly, proc objects with lambda declarations and proc declarations are slightly different. Proc object defined procs, if passed more arguments than are accounted for in their blocks, will simply cut off the extra arguments and proceed like nothing happened. Lambda defined procs will, in the same situation, throw an ArgumentError. Example: funct[2,3,4,5] will return 4 if it was instantiated with proc {|x| x*x}, but it will ArgumentError if it was instantiated with lambda {|x| x*x}.

I am really not sure why this distinction was even included in ruby at all; perhaps it was a backwards compatibility issue, but it seems to me that any function, whether represented by an actual function or a proc object, should throw an error when given the incorrect number of arguments. Just seems like it would make bugs a lot easier to find that way. You can check whether the proc was generated with a lambda expression using the Proc.lambda? function.

Procs also have some other cool methods, specifically for hashing and finding the number of arguments and currying. I would again direct you to the ruby doc page for more info. As for the useful part...they're as useful as any other function, and maybe even more since they can me passed around. Entirely first class!

So that's what the equivalent of a lambda function is in ruby, and that's how it's useful.

Friday, May 18, 2012

What are blocks in ruby and how are they useful?

Blocks in ruby are an incredible thing, and they are unlike anything in any other programming language, at least that I've encountered. A block is delimited by curly braces of a do...end section.


For example, arrays in ruby have a method called each (although technically it's an Enumerator, but think of it as basically a method for now). You can say:


a = [1,2,3]
a.each {|i| print i}


and ruby will output something like 123. The part inside the curly braces is a block. You can also have a block like this:


a.each do |i|
  print i
end


and it's the same thing. A block is basically a group of statements.


Each is basically a function that can take a block. To make your own function that can take blocks, you use the yield statement. For example, say you have a function like this (copied from ruby docs page):


def three_times
  yield
  yield
  yield
end


This yield statement is different in ruby than it is in, say python. Any function that has a yield statement inside it must take a block when it is called. You pass it a block by simply writing the block directly after the function call. Every time the execution in the function reaches a yield statement, the block is evaluated. So, writing three_times {print 'hello '} would output hello hello hello.


You can also pass values to the yield statement, like this:


def one_ten
  for i in 1..10
  yield i
  end
end


To access the value passed to yield, you write a block with a variable name in vertical lines at the front, like this: one_ten {|i| print i} or:


one_ten do |i|
  print i
end


Both of those will print 12345678910 to the output.


Here, we're really talking about iterators. Iterators are functions that have the yield statement in them, e.g. they can return one or more times with different values depending on how their yield statements are organized. In ruby, it seems that iterators are linked intrinsically to blocks.


One more thing. In python, for example, yield statements are sort of like return statements, but in ruby, yield statements actually evaluate to the last statement processed in the block. (Notice that technically, yield is not a statement, it's a function itself.) So you can have something like this, for example: 



def counting_up
a = 0
while a <= 10
a = yield a
end
end


counting_up do |yielded|
print yielded
yielded + 1
end

That will output 012345678910, because a will be set to whatever was yielded (a) plus 1 each time. Careful - if the yielded + 1 had not been there, the function would have run infinitely.

Blocks are useful in ruby in a couple of ways. One is the Array each method. There are other iterators as well built into ruby in different places: the Array.collect method, which takes a block and composes an array with the statements in the block applied to each item of the original array, is one. So something like [1,2,3].collect{|i| i+1} would output [2,3,4]. Again, look at the doc page for more examples.

So that's what blocks are in ruby, and how they're useful.

Thursday, May 17, 2012

What are hashes in ruby, and how are they different from regular hash tables?

A hash in ruby is basically a regular hash table with some cool added features. That is, it's a data structure that maps keys of any type (string, integer, mostly symbol, etc) to values (of not necessarily the same type).

Do define a hash in ruby, you type something like this: h = {:username => 'john302', :password => 'coolstuff', :age => 5}. Then to access the value stored with key :username, you would say h[:username], which in this example would evaluate to the string john302.

To define an empty hash, you can say h = {} or h = Hash.new (or h = Hash.new()).

The reason they're different from regular hash tables is you can define cool things like default values. For example, say you want a hash where an integer maps to its cube. You can type h = Hash.new({|hash, key| hash[key] = key * key * key}). This sets the default value of, say, h[5] to 125. I am pretty sure they use something akin to streams to do this. It's really interesting. Anyway, you can still store something in the hash, like, say, h[5] = 'cat', but if nothing is stored in a slot in the hash, it will default to its default value.

I think that the time it takes to do this is dependent on the function, though. For example, if you have a function that adds a key to itself a hundred times, mapping that function as the default for a hash will take a tiny amount of time. But computing a default value will actually do the work (add the key to itself a hundred times), so it may be slower. So hashes in ruby are not magic.

The really interesting thing is that this doesn't only work with integers. For example, if you say h = Hash.new {|hash,key| hash[key] = key + key}, then h['cat'] will default to 'catcat'. You have to be careful though, because not every operation is defined for every type. e.g., you shouldn't say h = Hash.new {|hash,key| hash[key] = key / key}, because then trying to say h[5] will evaluate to 1, but h['cat'] will raise a NoMethodError.

You can find out the other cool stuff about hashes at the documentation page on them.

So, that's what hashes are in ruby, and how they're different from regular hash tables.

What are arrays in ruby and how do they work?

Arrays are a built in data type in ruby, basically. You can define an array by typing something like a = [1,2,3], then you can get an element of the array with a[0], for instance. It's interesting to note that trying to say a[9] will NOT raise any sort of error, instead it will return a nil.


Just like in python, or any other mostly high-level language, arrays in ruby have a lot of built in methods. You can say [1,2,3] + [2,3,4], which will evaluate to [1,2,3,2,3,4], or you can do tricky things like intersection ([1,2,3] & [2,3,4] returns [2,3]) and union([1,2,3] | [2,3,4] returns [1,2,3,4]). Of course, array elements cannot only be integers, they can be whatever your heart desires.


There are as many or more built in methods for arrays as there are in python, and you can find them all at the documentation page for ruby arrays.


As for how they work, they are like arrays in any other language. They're an ordered sequence of objects, and the point is that you can access each one in constant time by providing its index. This is how they work.


So that's what arrays are, in ruby (and how they work). Or at least it's a start.

Tuesday, May 15, 2012

What is a ruby symbol?

Basically, a ruby symbol is an identifier that can't be changed. It's supposed to be, from my understanding, sort of a placeholder.


For example, say you have a bunch of hashes (dictionaries/hashtables). And they all have the same keys, but different values. Storing each key as a string would take up a ton of memory. Instead, you can store it as a symbol. With a symbol, each instance points to the same thing in memory.


To define a symbol, for example to store the name of something in a hash table, you type :name. You CANNOT say :name = 'john', because you can't "set" symbols to other things. Instead, you can define a hash or something like this: h = {:name => 'john', :occupation => 'carpenter'}.


Here, you are defining a representation of john the carpenter. You could have used strings as the keys in that hash table, but that's not really what strings are meant to be used for in ruby (as opposed to in python, where strings are immutable). You use the symbol as a placeholder, because it's easier and more conventional. Also, if you have 1,000 hashes to represent 1,000 people, using symbols will save you a pretty good chunk of memory.


You can get a string representation of the symbol if you need to with :name.to_s, but that doesn't make a lot of sense with a symbol. Basically, it seems to me that ruby symbols are a convenient way to enforce, or at least push people towards, a better convention for defining keys. Really, a symbol is a key, that you use to access something else.


That's what a ruby symbol is.

How do you declare variables and functions in ruby?

As it turns out, declaring variables and functions in ruby is fairly simple. To declare a variable, simply take a name, like string for instance, and assign it to a value with an = sign. For example, string = 'hello' would bind the name string to the string literal hello. Then, for example, puts(string) would print hello.

Functions are a little bit more complicated. To define a function, for instance to return the square of a number, type def square(x). Ruby will automatically return the last thing evaluated in the function body, so typing x *x will suffice for the next line. Ruby function definitions end with the end keyword. So the total function definition is:

def square(x)
  x*x
end

You can then call this function with square(5) or square 5. The parentheses don't matter, if I'm right. You can also use the return statement, like in other languages.

That's how you define functions and variables in ruby.

Sunday, May 13, 2012

How do you download/install/run ruby?

Ruby can be downloaded using your favorite package manager. On debian based linux distributions with apt-get, you can simply type sudo apt-get install ruby1.9.1 to get version 1.9.2 or ruby (the naming convention has something to do with library dependencies, which I don't quite understand, but 1.9.2 is the version that gets installed). You can check what version you have with ruby --version.


On Mac OSX with homebrew, its just brew install ruby. Easy!


If you're on windows, you can download RubyInstaller.


You can also compile ruby from source, using the instructions on the download page. Ruby is written in C, and it's open source, so you can view the entire source code on github.


You can run ruby using the ruby command. Ruby source files have the extension .rb, so say you have a file that you've written called helloworld.rb; you can run this using ruby helloworld.rb


You can also start the ruby interpreter using the irb command. After that, you can type any ruby command into the interpreter and it will evaluate it for you in real time, or you can type exit to close the interpreter.


That is how you download, install, and run ruby.