Sergio and the sigil

Playing with Ruby 1.9 - named parameters (sort of)

Posted by Sergio on 2008-12-31

I just installed Ruby 1.9.1 RC1 alongside my stable 1.8.6 installation. I'm planning to experiment with the changes and new language features for both using them in new code and upgrade old code (or at least protect old code from potential breaking changes.)

In light of the upcoming changes in C# 4, more specifically the addition of named and optional parameters, one of the new Ruby 1.9 features called my attention immediately.

Ruby, even 1.9, doesn't support named parameters in method calls. Instead, a common pattern is to provide a Hash parameter and call it something like options. Any optional argument is passed as an item of this hash, normally using a Symbol for the key. It helps that Ruby has special support for hash arguments, making the call look much cleaner:

def my_method(arg1, arg2, options)
  opt1 = options[:option1] || "default value for opt1"
  opt2 = options[:option2] || "default value for opt2"
  # ... etc ...
end

#calling the method:
my_method(val1, val2, { :option2 => "opt val 2", :something => "whatever"})
# simplified syntax
my_method(val1, val2, :option2 => "opt val 2", :something => "whatever")

In a way this is the poor man's version of named parameters, but it seems to do the job.

This is a very popular Ruby idiom (you can see that a lot in JavaScript as well,) so truly popular that the syntax was further simplified in 1.9. We can now ditch the arrow thingy and write the same exact code as follows:

#calling the method:
my_method(val1, val2, { option2: "opt val 2", something: "whatever"} )
# simplified syntax
my_method(val1, val2, option2: "opt val 2", something: "whatever")

The first syntax is identical to what you'd use in JavaScript. The second one is the same of named parameters in C# 4. I thought this was a welcome coincidence. See the C# 4 version below.

//NOTE: C# 4 code
void my_method(string arg1, string arg2, 
      string option1 = "default 1", string option2 = "default 2",
      string something = "")
{
  // ... method body here ...
}

//calling the method:
my_method(val1, val2, option2: "opt val 2", something: "whatever");

Language Envy - episode 0

Posted by Sergio on 2008-12-24

Although C# is the language that I can call myself proficient enough to make a living these days, there are other languages that I have to use for specific tasks (like JavaScript, SQL, XSLT.) I also like using other general purpose languages for pure exploration or pet projects. I'd include Ruby, ObjectiveC and PHP in this group.

When using other languages it often happens that I encounter features that I wish C# had or that the C#-equivalent was as easy (it works both ways — I miss some C# feature on the other side as well.)

In this series of undetermined length I will be posting some of the items from my wish list as I remember them.

The case statement

To start things off, let's check out C#'s case statement, straight from the language specification.

switch-statement:
    switch   (   expression   )   switch-block
switch-block:
    {   switch-sectionsopt   }
switch-sections:
    switch-section
    switch-sections   switch-section
switch-section:
    switch-labels   statement-list
switch-labels:
    switch-label
    switch-labels   switch-label
switch-label:
    case   constant-expression   : // <-- line 14
    default   :

I know that doesn't look like C# code. What I'd like to point is in line 14. The expression in each case label has to be a constant. I'm sure that helps making the switch statement compile to a very efficient MSIL code, but let's consider what we are missing because of that.

Here's a sample of what you can do in a Ruby case expression.

SIDE NOTE: The hawk-eyed reader will catch the terminology difference here. Many language constructs that are mere statements in C# are expressions in Ruby. But that's not the feature I'll write about today. Maybe in a future installment.
Months = %w(JAN FEB MAR APR MAY\
        JUN JUL AGO SEP OCT NOV DEC)

def get_month(value)
  case value
    when Date # class name (instance of?)
      return Months[value.month - 1]

    when /\d{4}-(\d{2})-\d{2}/ # Regular expression (matches ?)
      return Months[$1.to_i  - 1]

    when 1..12  # Range of values (contained ?)
      return Months[value - 1]

  end
end

puts get_month(Date.today)
puts get_month("2008-10-20")
puts get_month(8)

As you can hopefully see in the above example, the expressions in each when statement do not need to be constants (class names like Date are constants, by the way)

Ruby defines the === (triple equal) comparison operator that can be overriden in each class and is used in the case expression to test each when condition. This is usually read as "when value matches with this expression here...".

Not surprisingly, the built-in classes in Ruby do override the triple equal operator to add a more meaningful implementation for it. Range matches the values that are within the range. RegExp matches values that agree with the regular expression, Class objects match values that are instances of that class, etc.

I use this feature all the time and it's so convenient that I'd be thrilled to see it in C# one day.

So, what is my suggestion?

I wouldn't be a real programmer if I didn't try to sell my own suggestion, would I? Since IComparable is taken and means something different, I was thinking of maybe something like this.

public interface ICanMatch

Thank you LCNUG

Posted by Sergio on 2008-12-19

Thanks to the brave souls that ignored the incredibly exaggerated Winter storm warnings and insane weather forecast for last night. These folks came to the LCNUG meeting and were home before the first snow flake hit the ground. Also, thanks LCNUG for inviting me to talk, I hope you enjoyed at least a little bit.

The material I had to show in my presentation would no doubt fill an entire day (because it came from a full-day class I previously led) but we are not that crazy so we decided that:

  • Doesn't matter how much of the material we cover, what we cover we will cover well.
  • It would be best to talk about less things but get more value out of that than talk about a whole lot of things and feel like you just wasted two hours of your life.
  • Go only as far as our stamina (and storm anxiety) allowed us to.
  • Ask, ask, ask. Don't go back home with any lingering question.
  • Well, keep that under the 2-hour mark, will you?

I never thought we would have enough time to see the entire material or even see some jQuery stuff. But I'm confident that what we have seen there will allow anyone that is starting to take JavaScript seriously to jump on jQuery (or YUI or Prototype.js, etc) and be able to effectively read the docs, the samples, and even the source code.

I'm trying to get clearance with my company to share the presentation material. Either by a download link here or directly emailing the attendees. Sit tight.

Talk: JavaScript - Beyond the Curly Braces

Posted by Sergio on 2008-12-09

Next week I'll be speaking at the Lake County .NET Users' Group, in Grayslake, IL. The topic will be something that is near and dear to me and which I have talked and written about quite a number of times.

If you live in the North 'burbs, come and support our local group. You can register for this event here.

JavaScript - Beyond the Curly Braces

One of the greatest problems with JavaScript is its superficial syntax resemblance of C-style languages. We call it the curse of the curly braces.

That is also a very large source of frustration for developers trying to learn JavaScript beyond the basics. Thinking that JavaScript is somehow related to Java or even "It's almost like C# but a little simpler" is an unfortunate and common occurrence that can only lead to trouble.

In this session we will analyze some of the fundamental differences between JavaScript and C#/Java. We will highlight the pitfalls that can trap us and the appropriate workarounds for them.

Time permitting and if there's interest we will take a look at Idiomatic JavaScript, which will help us understand how JavaScript is being written these days. Learning about this will also help you when trying to read the source code or even the documentation and samples for popular JavaScript libraries like jQuery, Prototype, YUI, etc.

Reusing Views in ASP.NET MVC for Ajax Updates

Posted by Sergio on 2008-12-05

The other day I came across this post in Marteen Balliauw's blog where he demonstrates and interesting way to make the same ASP.NET MVC view render correctly from both a regular request and an Ajax request.

In Marteen's post he uses a custom ActionFilterAttribute to detect the Ajax call and replace the standard master page with an unadorned Empty master page.

I liked the idea that you can add that behavior to any action simply by bolting that attribute to it.

What I'm going to illustrate here is a variation of that idea that can be used when you have your own base class to all your controllers, which is something I always do.

SIDE NOTE: I have the habit of creating base classes for all the important things in my ASP.NET applications right after I create the project. I carried this habit from the ASP.NET Webforms-style to the MVC projects. So I typically have ApplicationController, ApplicationView<T>, PartialView<T>, ApplicationMaster, etc. These classes start off empty but code starts finding its way to them rather quickly.

What I'm going to do is override the Controller.View() method to detect the Ajax calls and replace the master page right there.

public abstract class ApplicationController: Controller
{
  protected override ViewResult View(
            string viewName, string masterName, object model)
  {
    if(IsAjaxRequest)
      return base.View(viewName, "Empty", model);

    return base.View(viewName, masterName, model);
  }

  protected virtual bool IsAjaxRequest
  {
    //Both Prototype.js and jQuery send 
    // the X-Requested-With header in Ajax calls
    get
    {
      var request = ControllerContext.HttpContext.Request;
      return (request.Headers["X-Requested-With"] == "XMLHttpRequest");
    }
  }
}

With that in place I don't need to change anything in my action code to start supporting the Ajax calls (as long as the controller inherits from the above base class)

public class SampleController : ApplicationController
{
  public ActionResult Index()
  {
    return View();
  }

  public ActionResult Details(int id)
  {
    var user = new UserInfo {Name = "user" + id, Age = 30};
    return View(user);
  }
}

My Index action calls the Details action using both a regular request and an Ajax call, for the sake of the example.

<%@ Page Title="" Language="C#" 
  MasterPageFile="~/Views/Shared/Site.Master" 
  AutoEventWireup="true" 
  CodeBehind="Index.aspx.cs" 
  Inherits="MvcBeta1.Views.Sample.Index" %>
<asp:Content ID="Content1" 
        ContentPlaceHolderID="MainContent" runat="server">
<h2>Sample View Index</h2>
<%= Html.ActionLink("Go to Details", "Details", new { id = 123 })%>
<hr />
<input type="button"  id="loadDetails" value="Load with Ajax" />
<div id="detailsDiv" style="background-color:#aaa;">
[details should load here]
</div>

<script>
  $(function() {
    $('#loadDetails').click(function() {
      $('#detailsDiv').
        load('<%= Url.Action("Details", new {id = 123}) %>');
    });
  });
</script>
</asp:Content>

The Details view is trivial. It's just a table.

<%@ Page Title="" Language="C#" 
  MasterPageFile="~/Views/Shared/Site.Master"
  AutoEventWireup="true" 
  CodeBehind="Details.aspx.cs" 
  Inherits="MvcBeta1.Views.Sample.Details" %>
<asp:Content ID="Content1" 
        ContentPlaceHolderID="MainContent" runat="server">
  <h2>Details for <%= ViewData.Model.Name %></h2>
  <table border="1">
    <tr><th>Col 1</th><th>Col 2</th><th>Col 3</th></tr>
    <% for(int i=1; i<= 5; i++) { %>
      <tr>
        <td>cell (<%= i %>, 1)</td>
        <td>cell (<%= i %>, 2)</td>
        <td>cell (<%= i %>, 3)</td>
      </tr>
    <%} %>
  </table>
</asp:Content>

When at the Index page we can click on the "Go to Details" link and see the full rendering of the Details view.

If we had instead clicked the "Load with Ajax" button we would cause a simpler version of that page to be inserted in the detailsDiv element (note that the tabs and the blue background that surrounds the table did not come in the rendered content.)

Of course, ASPX files are not the indicated place for placing content that can be used in partial updates, ASCX files would be a better choice for that. That said, sometimes it can be really convenient to have this ability.