Posted on 10/4/2008 2:51:21 PM by Justin Etheredge
I just finished giving my talk on IronRuby at the Richmond Code Camp 2008.2. It was titled "Microsoft and Ruby Sittin' in a Tree". I tried to cover a huge number of features in Ruby very quickly and then show off a few Ruby snippets that demonstrate many of its cool features. As usual you probably won't get a huge amount out of the slides without seeing the accompanying presentation, but you can still go through it if you would like. I have included the source for my demos in the zip as well, and that is probably the more interesting part. It has some basic language primer, which I didn't get to in the presentation, and it also has some more advanced "showy" demos.
I demonstrate 5 main things in the code samples:
1) A proxy class that allows you to pass an instance of a class to its constructor and then intercept method calls and do something. Just wanted to show how easy it is in Ruby with method_missing.
2) Second it shows off a recorder which lets you call a bunch of methods on a recorder object and then play those calls back against a target object. I wanted to implement this and search online and found an example of Jay Field's blog. I studied his implementation for mine, so I have to give props.
3) Third I showed off a bit of Meta-Programming which uses class_eval and define_method to create new methods on a class.
4) Fourth I showed off a bit of .net Interop which just displays a form with a field and a button. It shows assigning a block to use as an event handler.
5) Fifth I showed how to consume a WSDL file in Ruby and then call the web service. Then I use REXML to parse the resulting XML and display it in the console. This the only of the five demonstrations that won't run yet under IronRuby.
If you would like to see the presentation or accompanying source files, you can download it here.
Posted on 9/10/2008 10:29:51 PM by Justin Etheredge
You may have read that title and thought that this was going to just be another one of those "learn a different paradigm to make you think different" posts. Well, it isn't. Those posts aren't bad, and I have made a few of them, but this is a much less creative post...
Just to get this out of the way, all of the following code is covered under the MS-PL license.
If you haven't had the luxury of getting to play around with the Ruby libraries then you are missing out. In fact, if you haven't ever used them, then go check out some of the classes in the library to see just how powerful it really can be. For example, check out the String class in Ruby and you will see a list of methods that looks like this:
% * + << <=> == =~ [] []= bytes bytesize capitalize capitalize! casecmp center chars chomp chomp! chop chop! concat count crypt delete delete! downcase downcase! dump each each_byte each_char each_line empty? end_with? eql? gsub gsub! hash hex include? index initialize_copy insert inspect intern length lines ljust lstrip lstrip! match new next next! oct partition replace reverse reverse! rindex rjust rpartition rstrip rstrip! scan size slice slice! split squeeze squeeze! start_with? strip strip! sub sub! succ succ! sum swapcase swapcase! to_f to_i to_s to_str to_sym tr tr! tr_s tr_s! unpack upcase upcase! upto
There is a lot of awesome functionality in there which could be really useful in C#. If only we had some code in C# that performed all of these actions! Oh wait, IronRuby is written in C#! We can just look up the IronRuby methods in the source.
So, how do we find these methods? Well, the IronRuby team has two attributes that help us find the method that we are looking for. One is called the "RubyClassAttribute" and the other is called "RubyMethodAttribute". If we look in the IronRuby source and search for "chomp" we will actually find a few method that look like this:
[RubyMethod("chomp")]
public static MutableString/*!*/ Chomp(CodeContext/*!*/ context, MutableString/*!*/ self) {
return InternalChomp(context, self, RubyUtils.GetExecutionContext(context).InputSeparator);
}
[RubyMethod("chomp")]
public static MutableString/*!*/ Chomp(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]MutableString/*!*/ separator) {
return InternalChomp(context, self, separator);
}
[RubyMethod("chomp")]
public static MutableString/*!*/ Chomp(CodeContext/*!*/ context, MutableString/*!*/ self, object separator) {
return separator == null ? self : InternalChomp(context, self, Protocols.CastToString(context, separator));
}
So, here you can see that all of these methods are calling out to another method to do their bidding called "InternalChomp". We were lucky in that the string class is the only class which has a "chomp" method, but if we had multiple type then that is where the "RubyClassAttribute" can help you out. If we look at the top of the class that we found the "Chomp" methods in we will see this attribute declaration:
[RubyClass("String", Extends = typeof(MutableString), Inherits = typeof(Object))]
public class MutableStringOps {
This is pretty self explanatory. This class represents methods that are on the Ruby "String" class, which is represented by the CLR type MutableString. If we go back to the "InternalChomp" method that we saw earlier, then we will see this code:
private static MutableString InternalChomp(CodeContext/*!*/ context, MutableString/*!*/ self, MutableString separator) {
if (separator == null)
return self;
// Remove multiple trailing CR/LFs
if (separator.Length == 0)
return RubyUtils.FlowTaint(context, self, ChompTrailingCarriageReturns(self, false));
// Remove single trailing CR/LFs
MutableString result = RubyUtils.FlowTaint(context, self, CreateSubClass(context, self, MutableString.Create(self)));
int length = result.Length;
if (separator.Length == 1 && separator.GetChar(0) == '\n') {
if (length > 1 && result.GetChar(length - 2) == '\r' && result.GetChar(length - 1) == '\n') {
result.Remove(length - 2, 2);
} else if (length > 0 && (self.GetChar(length - 1) == '\n' || result.GetChar(length - 1) == '\r')) {
result.Remove(length - 1, 1);
}
} else if (EndsWith(result, separator)) {
result.Remove(length - separator.Length, separator.Length);
}
self.Version++;
return result;
}
While this method may not be particularly interesting there is a lot of code you can go through in the IronRuby codebase to give you plenty of ideas. For example, everyone complains about C#'s lack of a good Range class. So why not go into the IronRuby source and get a few ideas for implementing your own C# Range class? So, go get the source for IronRuby, play around with it, and let me know what you find.
Posted on 8/12/2008 11:51:27 PM by Justin Etheredge
Click here to view the entire IronRuby via C# series
In the last part of this series we talked about hashes in Ruby and C# and we saw how they are very close in functionality. In this entry we are going to start looking at the parts of Ruby that do not easily translate directly into C#. In a few past posts you have seen some parts of Ruby that vary a bit from C#, but in most cases the languages are still very similar. You will now start to see the features that people brag about when they tout Ruby's power over most statically typed languages.
The first feature that we are going to look at is called "duck typing". It is really less of a feature and more an underlying principle of the language. "Duck typing" refers to the way in which objects are used polymorphically in Ruby. In C# an object's class is its type and it represents the mechanism through which object can be manipulated. So, in C#, if you wanted to interact with a class then you need to know its type, one its base types or an interface supported by the type. So, lets define a tiny hierarchy here:
public abstract class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public abstract int VacationDays { get; }
}
public class Manager: Employee
{
public override int VacationDays
{
get
{
return 25;
}
}
}
public class Developer: Employee
{
public override int VacationDays
{
get
{
return 18;
}
}
}
In this you can see that we have a Employee class with Developer and Manager child classes. If we wanted a method to be able to operate on either a Manager or a Developer then we would create a method that used our Employee base class like this:
public void PrintEmployeeVacation(Employee employee)
{
Console.WriteLine("Vacation Days: {0}", employee.VacationDays);
}
And now we could pass either a Manager or Employee in and we would print out their vacation. So, how would we do this in Ruby? Well, in Ruby this hierarchy would look like this:
class Employee
attr_accessor :first_name
attr_accessor :last_name
end
class Manager < Employee
def vacation_days
25
end
end
class Developer < Employee
def vacation_days
18
end
end
But if we created the same method then we would create it to look like this:
def PrintEmployeeVacation(employee)
puts "#{employee.vacation_days}"
end
So, that looks very similar to the C# method, but there aren't any types. So how does that work? If we aren't specifying any types, how does Ruby know that it is valid to call "vacation_days" method on the object? This is where Ruby's duck typing comes in. Since in Ruby a class is not its type, Ruby simply relies on whether or not a class has an implementation of a particular method. Which is why it is called "duck typing", because "if it walks like a duck, and talks like a duck, then it must be a duck"!
And since Ruby doesn't rely on anything other than the fact that a class supports a particular method, we see that there is nothing regarding the "vacation_days" method in the "Employee" class at all. Ruby has no concept of an abstract class or method. And guess what, that means that these classes don't need to share a base class! In fact, Ruby has no concept of interfaces, and so you don't need one of those either. So, we could define these classes like this:
class Manager
attr_accessor :first_name
attr_accessor :last_name
def vacation_days
25
end
end
class Developer
def vacation_days
18
end
end
Notice that there is no first name and last name in the Developer class. I took those out so you can see that they don't share a base class and they don't even have an identical implementation. Ruby just doesn't care. It doesn't matter to the "PrintEmployeeVacation" method because it only uses the "vacation_days" method. This means that any class which has a method called "vacation_days" which returns a value that can be used in the "puts" method will work in this method. This means that we could change the Developer class to this:
class Developer
def vacation_days
"18"
end
end
And it would still work. Since the string "18" is valid in the context of our method, then execution would occur as normal. How is that for flexibility?
But all of this flexibility also comes at a cost. In fact, most of you who are used to static languages may be sitting there with your mouth agape in horror. You are probably thinking "you can pass anything into that method, and if the 'vacation_days" method isn't supported then it will just blow up!". What about if an object is passed in that has the method which doesn't perform the same operation, or return a valid result, or takes parameters? Well, you will get a runtime error. Because of that you may be shaking your static head and saying, "but how would you ever control the behavior!?"
The answer is unit testing. In dynamic languages, just like in static languages, everything should be unit tested. Sure the programmer must to have better knowledge of what an object needs in order to be passed into a particular method, but the lack of compile time checking is one of the fundamentals of dynamic programming. It is not a weakness, it is a feature! If the thought of not having every parameter on every method checked for type makes you lose sleep, then dynamic languages may not be for you. The important thing is that you must use heavy testing in order to flush out these errors and keep your code quality high.
I hope you enjoyed this look at the power and flexibility of Ruby's duck typing, in a future post we are going to delve a bit more deeply into Ruby's type system by introducing you to modules in Ruby. Have fun!
Posted on 8/3/2008 11:41:08 PM by Justin Etheredge
Click here to view the entire IronRuby via C# series
Welcome back for part 6 in my learning Ruby via C# series. In the last entry we discussed arrays in Ruby and C#. We saw how Ruby arrays were actually more like Lists or Collections in C#. They are able to be modified, appended, resized, searched, sorted, etc... In this entry we are going to discuss an equally powerful data structure, the hash or associative array. The hash is close to the Dictionary or Hashtable classes in C#. We are going to use the Dictionary class in this entry since it is the more often used class.
So, in C# if we wanted to declare a Dictionary and populate it with a few keys and values we would do something like this:
var jobs = new Dictionary<string, string>();
jobs.Add("Developer", "Jimmy Dean");
jobs.Add("Senior Developer", "John Smith");
jobs.Add("Network Engineer", "Bob Franklin");
In Ruby hashes are a first class member of the language, so they have their own syntax for declaring them. One way to declare a hash looks like this:
jobs = {}
jobs["Developer"] = "Jimmy Dean"
jobs["Senior Developer"] = "John Smith"
jobs["Network Engineer"] = "Bob Franklin"
But you could also do it all in one line by separating the key and the value with the "=>" operator:
jobs = {"Developer" => "Jimmy Dean", "Senior Developer" => "John Smith", "Network Engineer" => "Bob Franklin"}
Sweet. But in Ruby, symbols are the preferred way of representing the keys in hashes. It would be similar to defining an enumeration in C# and using that for the Dictionary key:
public enum Jobs
{
Developer = 1,
SeniorDeveloper = 2,
NetworkEngineer = 3
}
var jobs = new Dictionary<Jobs, string>();
jobs.Add(Jobs.Developer, "Jimmy Dean");
jobs.Add(Jobs.SeniorDeveloper, "John Smith");
jobs.Add(Jobs.NetworkEngineer, "Bob Franklin");
In Ruby we would set it up like this:
jobs = {}
jobs[:Developer] = "Jimmy Dean"
jobs[:SeniorDeveloper] = "John Smith"
jobs[:NetworkEngineer] = "Bob Franklin"
So now that we know how to build up our hashes, how do we get our entries back out? We probably know how to do this in C#:
Console.WriteLine(jobs[Jobs.Developer]);
That would send "Jimmy Dean" out to the console. Since we know how to do it in C#, we already know how to do it in Ruby!
puts jobs[:Developer]
Very cool. Ruby hashes also support the "each" method just like the Ruby array. In C#, we would loop through each item in the dictionary like this:
foreach (KeyValuePair<Jobs, string> job in jobs)
{
Console.WriteLine(String.Format("{0} {1}", job.Key, job.Value));
}
We could also cheat and use my "Each" extension method that I defined:
public static void Each<T>(this IEnumerable<T> list, Action<T> func)
{
foreach (T item in list)
{
func(item);
}
}
And then our C# code looks like this:
jobs.Each(j => Console.WriteLine(String.Format("{0} {1}", j.Key, j.Value)));
Looks better and pretty much what our Ruby version looks like:
jobs.each { |key, value| puts "#{key} #{value}" }
So now we have seen how to build up, access, and then iterate through our hashes. But what is the coolest use for hashes in Ruby? Well, we mentioned it in an earlier post, and that is method parameters! It allows us to have a variable number of named parameters. As C# developers we are not used to having named parameters, but if you think about it, if you name parameters then their order is not important. So, if you pass hashes for parameters then you can change method signatures without worrying about breaking older code. Lets look at a method real quick:
def print_names(params = {})
first_name = params.fetch(:first_name, "John")
last_name = params.fetch(:last_name, "Doe")
job = params.fetch(:job, "No Job")
puts "#{first_name} #{last_name} Job: #{job}"
end
You can see that we are pulling our variables out of the hash that is passed into the method, providing default values. The default value is the second parameter of the "fetch" method. So, we could call this method like this:
print_names(:first_name => "Justin", :last_name => "Etheredge", :job => "Programmer")
Or like this:
print_names(:job => "Programmer", :last_name => "Etheredge", :first_name => "Justin")
Or this:
print_names(:first_name => "Justin", :job => "Programmer")
Or even like this:
print_names
Are you starting to see the flexibility of this method of parameter passing? If later on we need to add a parameter for number of years in position:
def print_names(params = {})
first_name = params.fetch(:first_name, "John")
last_name = params.fetch(:last_name, "Doe")
job = params.fetch(:job, "No Job")
number_of_years = params.fetch(:number_of_years, 0)
puts "#{first_name} #{last_name} Job: #{job} Number of years: #{number_of_years}"
end
All of our old code will still work. Now this isn't all ponies and gumdrops though, you can see that it makes calling methods much longer affairs. It also doesn't help that our method's only parameter is "params = {}". That doesn't exactly provide us anywhere to start for calling the method. You have to look into the method to see what you need to pass, and here you see that we are fetching the values up front and putting them into local variables. But what if the method was long and didn't do this up front? Then you might have references to the hash strewn all throughout your method and you would have to hunt for them. The only other option is to have good documentation for your methods, which obviously won't always happen. Suffice to say, that this can make a method very hard to call in the hands of a poor programmer, but then again, Ruby is all about giving sharp tools to sharp people.
Another flexibility that this gives you is the ability to do different things based on which items are in the hash. Since Ruby does not support method overloading, it makes it hard to have multiple methods perform different functions based on their parameters. With hashes though you can check if certain items exist in the hash using the "has_key?" method and then perform different actions based on what is passed.
As you have seen, hashes are incredibly useful data structures in Ruby. When you combine them with methods they can give you flexibility that most languages just don't have. There are many more things you can do with the Ruby hash, but you'll have to go check out the Ruby hash docs yourself.
I hope that you have found this little tutorial helpful!
Posted on 7/28/2008 1:02:55 AM by Justin Etheredge
Click here to view the entire IronRuby via C# series
Welcome back for part 5 in my learning Ruby via C# series. In this post I want to cover hashes (or associative arrays) and arrays in Ruby. These two data structures are used quite often in Ruby, and so we are going to spend a little bit of time going over them. But first I want to clear up some mistakes that I made in the first post of the series. In the first post I had explained what attribute accessors were and I showed a class that looked like this:
class Person
attr_accessor :count
@@count2 = 0
def count2
@@count2
end
def count2(value)
@@count2 = value
end
end
Well, that isn't exactly correct. Well, I was trying to show static variables in Ruby and I wanted to show the static version of "attr_accessor". The first item I wanted to clear up is that I used instance method in this class because we had yet to cover static methods. This was done on purpose, but I wanted to show it as static now. The second thing is that you can do this in a shortened manner using the cattr_accessor method. The "c" stands for "class" since Ruby calls these "class variables and methods" and not "static". The only problem is that this is part of ActiveSupport and not the standard Ruby libraries. ActiveSupport is a library of helper methods for Ruby on Rails, and currently has some issues running under IronRuby so I am not going to use it for now.
The second thing that I wanted to clear up, which actually was a mistake, is that the two "count2" methods are not what is defined. The second "count2" method should have an "=" between the word "count2" and the "(" that starts the argument list. So, if we don't use the "cattr_accessor" method, our class (using static methods) will look like this:
class Person
attr_accessor :count
@@count2 = 0
def self.count2
@@count2
end
def self.count2=(value)
@@count2 = value
end
end
And then we could access these new static methods like this:
Person.count2 = 123
puts Person.count2
Phew, now we can finally get to the new stuff! Let's first talk about arrays. An array in Ruby is essentially the same as an array in C#. Lets say we wanted to declare an array of integers in C#:
int[] numberArray = { 1, 2, 3, 4, 5 };
Okay, now lets do the same thing in Ruby:
number_array = [1, 2, 3, 4, 5]
You can see that Ruby lets us define an array simply using square brackets and assigning the value to a variable. Now, while a C# array is immutable (meaning we can't modify it) a Ruby array can be modified. So, in C# in order to add the number "6" to our array above we would have to do this:
int[] numberArray2 = new int[numberArray.Length + 1];
Array.Copy(numberArray, numberArray2, numberArray.Length);
numberArray2[numberArray2.Length - 1] = 6;
But in Ruby, we could simply do this:
number_array << 6
This uses the "<<" operator, therefore making Ruby arrays more similar to a C# collection than a C# array. In fact, Ruby arrays has methods for deletion and insertion. If we were to say:
number_array.delete(3)
Then when we output the array, we would get "[1,2,4,5]". This is important because Ruby arrays are 0 based, just like C#. So, the "delete" method removes the item "3", not the index (in fact, if there were more than one "3", it would remove all of them). We would have to use the method "delete_at" in order to remove an item at an index:
number_array.delete_at(3)
We can also insert into the array using "insert" (the first parameter is the index, the second is the value):
number_array.insert(2,4)
So, what if we wanted to add an item to the end (without the "<<" operator):
number_array.push(7)
Okay, so we have a push method, what about pop? Of course, in Ruby you can use arrays just like stacks!
number_array.pop
Like I said before, in Ruby arrays are zero based, just like C#. They even use the same method to access the items. In C#:
int value = numberArray[0];
In Ruby:
value = number_array[0]
But what if we just wanted to see the last item in the array, but not remove it? In C# we would have to use the length of the array minus one:
int value = numberArray[numberArray.Length - 1];
But in Ruby, you can access arrays using negative indexes:
value = number_array[-1]
Negative arrays are indexed from the end of the array. How cool is that? Another cool thing you can do is use ranges to access an array:
number_array[0..2]
This would return "[1,2,3]". As you can see, the Ruby array is very flexible.
So, enough about accessing arrays, what if we want to do some operations on these arrays. Lets add up all of the items in C#:
int total = 0;
foreach (int i in numberArray)
{
total += i;
}
Console.WriteLine(total);
And what about in Ruby?
total = 0
number_array.each do |i|
total += i
end
puts total
Lets do it more efficiently in C# using the LINQ aggregate method (if haven't seen Aggregate (also called Fold) you can see an implementation and explanation here):
int total = numberArray.Aggregate((accumulator, i) => accumulator + i);
Console.WriteLine(total);
And then we will do it in Ruby using inject:
total = number_array.inject(0) { |accumulator, i| accumulator + i }
puts total
Sweet. You can really see how far C# has come to closing the gap in C# 3.0 with Linq. Before C# 3.0 and Linq we would be losing quite a bit of expressiveness here. Again, we can use the "select" method in C# and the "map" method in Ruby to transform items in an array. If we wanted to multiply each item in our array by 2, we could do this in C#:
var result = numberArray.Select(i => i * 2);
In Ruby we could do it like this:
number_array.map { |i| i * 2 }
Phew, I think we have had about enough with Arrays in Ruby. There is so many things that Ruby arrays can do, and we just don't have the space to cover all of it. Go check out the Ruby docs if you want to see all of it.
Well, I was going to discuss hashes, but I think that arrays went on for a lot longer than I had originally planned. This seems to be a recurring theme, but there is just so much to talk about! I hope that you enjoyed the post and in the next one we are going to start talking about hashes.