ARCHIVE: October, 2006

Initiating AJAX requests can be addicitive; you start with independent requests, and soon you need to initiate chained requests. Executing chained requests is easy, but how do you pass common variables across these requests.

I have meddled with three ways, the first two depends on the response type, and the third is my favourite. Sample codes shown using Prototype javascript library, but are applicable to other libraries too:

1. Through JSON object response

This way is only applicable if your response type is a JSON object. The common variable is passed through URL parameter from the first request, then embedded in JSON object response to be used by the next request. Example:

Client script

// first request
new Ajax.Request('/url/path', {parameters: 'common_var=hello', oncomplete: handleComplete})

// handle first request response
function handleComplete(xmlHttpReq, json) {
   common_var = json.common_var

  // initiate second request using common_var
  new Ajax.Request('/url/path', {parameters: 'common_var=' + common_var, .... })
}

Server script

# server side JSON object response
{common_var: '<%= params[:common_var] %>', ... <other properties>}

2. Through XML response

Similar to the previous method, this way is applicable if your response type is XHML instead of JSON object. The common variable is embedded in XML response. The element will then referenced by second request using Javascript. Example:

Client script

// first request
new Ajax.Request('/url/path', {parameters: 'common_var=hello', oncomplete: handleComplete})

// handle first request response
function handleComplete(xmlHttpReq, json) {
   resDoc = xmlHttpReq.responseXML
   common_var = resDoc.getElementsByTagName("common_var")[0].firstChild.data

  // initiate second request using common_var
  new Ajax.Request('/url/path', {parameters: 'common_var=' + common_var, .... })
}

Server script

# server side XML response
<response>
   ... other elements
   <common_var><%= params[:common_var] %></common_var>
</response>

3. Through Prototype AJAX.Request options

This is my preferred way, because it does not involve a round-trip to the server. Initiate Ajax.Request with by adding common_var as one of the request options, and register a oncomplete global event handler through AJAX.Responders.

Note you can only do this through global event handler, because the first argument passed to the event handler is the AJAX.Request object. With it, you can easily retrieve the common_var request options. While inline event handler shown in previous example passes XMLHttpRequest object instead of Ajax.Request object. Example:

Client script

// first request
new Ajax.Request('/url', {parameters: 'id=<%= id %>', id: <%= id %>})

// register global event handler
Ajax.Responders.register({onComplete: handleComplete})

// handle first request response
function handleComplete(ajaxReq) {
   common_var = ajaxReq.options.common_var

  // initiate second request using common_var
  new Ajax.Request('/url/path', {parameters: 'common_var=' + common_var, .... })
}

Faces

MON, 16 OCT 2006

FacesI joined a photo marathon organised by Canon last Saturday.

There were four themes given out throughout the day at 3-hour interval: 2 hours for shooting, an hour for uploading files and resting at the same time.

The image on left was my attempt for the first theme, “Faces“, I thought it will be shortlisted, but it was not. The second theme was “Power: Simply Red“; out of a whim of fun or maybe an act of desperation, I submitted a direct interpretation, a power-socket-with-a-red-button shot. The young chap that transferred my file, kept smiling all the way. Must be thinking who is this dumbass?

I left after the second theme for an appointment. Besides, my feet were aching and the haze was pretty bad too; the Pollutant Standards Index (PSI) index almost hit unhealthy level.

It all started with Nick asking a question like this in Singapore Ruby Brigade. How come?

String === String
=> false
# but
String == String
=> true

Let’s start with the easy one first:

Equality (==, eql?, equal?)

#== is the common equality method that compares object values, ignoring the object id. #eql? is the alias of #==, so they are the same. Btw the “#” prefix means it is an instance method (just in case), without the prefix, it means a class method.

The stricter version of is #equal? compares the object id. Example:

"test" == "test"         
# returns true, both have the same value, i.e. "test"

"test".equal?("test")  
# returns false, because "test" (left) is a different object from "test" (right), where "test".__id__ != "test".__id__

Case Equality (===)

=== is the case equality method, in English it means it is called internally when you use ‘case’ statement, but of course, it can also be called outside the case statement.

=== method functions differently, depending on the caller class type.

If you call it on a Class, it will check if the compared object is an instance/descendant of the class. On Object, it is the same with #== method. Please refer to Ruby documentation for more information on how it performs on different class types.

String === "test"    
# returns true because "test" is an instance of String

"test" === "test"
# returns true, because both objects have the same value or "==" returns true

"test" === "different test"
# returns false, because the two objects have different values.

Just a bit more spice, on Ruby on Rails (RoR) framework, the Range class overrides “===” method to returns true if the compared value is found in the in the range values.

1..10 === 1    # returns true
1..10 === 11   # returns false

case var
   when 1..10
       "do some stuff here"
   when 11..20
       "do something else here"
   else
       "out of range"
end

So back to the one-million-dollar question, why then String === String returns false?

Calling String in the runtime environment, returns a Class object that represents String class type. If you call String.__id__, it will return the object id of Class object. Thus:

String === String
# returns false, because String (right) is treated as a Class object, passed as an argument to String  "===" method.

And… I think you get it, obviously Class object is not an instance of String class. Sweet.

And why String == String returns true?

You should be able to answer it by now. =)

Overriding Methods in Ruby

THU, 5 OCT 2006

If you are new to Ruby, you may bump into some confusion when overriding methods, especially when you still need to refer to the old or parent methods. Just to share some notes I have taken on overriding methods in Ruby.

You can override a method by either extending a class or by re-declaring an exisiting class with just the new methods.

Let’s dive into codes, Ruby codes speak a thousand words.

Overriding Parent Instance Method

This is the typical way in Object-Oriented programming, by extending a class.

class Parent
    def call_method
        'parent'
    end
end

class Child < Parent
    def call_method
        super + '-child'     #return: 'parent-child'
    end 
end

Overriding Parent Class Method

Class methods are a bit more confusing, because there are different ways to declare them. Well, welcome to ruby, there are a lot of magic here.

There are three ways to declare class methods:

class ClassName
    def ClassName.method_1
        ...
    end

    def self.method_2
        ...
    end

    class << self
        def method_3
            ...
        end

       def method_4
           ...
       end
    end
end

To override a class method:

class Parent
    def self.call_method
        'parent'
    end
end

class Child < Parent
     def self.call_method
         superclass.call_method + '-child'    #return: 'parent-child'
     end

end

Overriding Method of Existing Class

To override a method in an existing class, you just have to re-declare the class with the new methods. If you need to call the old method in your new method, you first have to create an alias of for the old method. You can use either alias or alias_method. This is something that I dont’ see in Java, pretty cool.

Note that you don’t need to redeclare Parent extension. And also note the difference in declaration between alias and alias_method; alias is a reserved keyword in Ruby, while alias_method is just a function call.

class Child
  alias old_call_method call_method

  def call_method
     old_call_method + '-new'   #return 'parent-child-new'
  end
end

class Child
  alias_method :old_call_method, :call_method

  def call_method
     old_call_method + '-new'   #return 'parent-child-new'
  end
end

Or you can also do it this way:

class Child
   alias_method :old_call_method, :call_method
   alias_method :call_method, :new_call_method

   def new_call_method
     old_call_method + '-new'   #return 'parent-child-new'
   end
end

# If you are using RailsOnEdge, this is the shortcut 
class Child
   alias_method_chain :call_method, :extra
  
   def call_method_with_extra
        call_method_without_extra + '-new'    #return 'parent-child-new'
   end
end