Archive for the 'Tricks' Category



“AkitaOnRails” On Ruby Symbols

Monday 26 November 2007 @ 6:24 am

RubyLearning recently caught with Fabio Akita from Brazil and got his viewpoint on one of the vexing areas for beginners in Ruby - Symbols.

Fabio AkitaFabio Akita is a Brazilian Rails enthusiast, also known online as “AkitaOnRails”. He regularly write posts on his own blog and had published the very first book tailored for the Brazilian audience called “Repensando a Web com Rails”. He is now a full-time Ruby on Rails developer working as Brazil Rails Practice Manager for the Utah company Surgeworks LLC.

Ruby is very similar to many other object oriented languages. You can find similar constructs from non-dynamic languages as Java or C#. On the other hand, to start grasping all the possibilities of Ruby one has to invest some time learning what we call ‘Rubyisms’. One example is something called a *symbol*.

This is more obvious when you start learning Ruby through Rails. Much of Rails power comes from the fact that it uses a lot of rubyisms. Let’s see one example: (Note: You may want to brush up on Symbols and ActiveRecord before going through the examples that follow.)

class Transact < ActiveRecord::Base
  validates_presence_of :when
  validates_presence_of :category, :account
  validates_presence_of :value
  validates_numericality_of :value

  belongs_to :category
  belongs_to :account
end

‘class’ we understand, after all, the mainstream languages are ‘object-oriented’. But what are all those colons doing through all the code? Those denote Symbols. More important, the colons represent initializers of the class Symbol.

This can be quite confusing considering that the normal way of initializing an object is:

Symbol.new

The ‘new‘ call asks for the standard ‘initialize‘ method defined within the class. Turns out that this method is private, the idea being that all symbols should be instantiated with the colon notation.

Symbols are used as identifiers. Some other languages could simply use Strings instead of Symbols. In Ruby, it would become something like this:

class Transact < ActiveRecord::Base
  validates_presence_of "when"
  validates_presence_of "category", "account"
  validates_presence_of "value"
  validates_numericality_of "value"

  belongs_to "category"
  belongs_to "account"
end

Not so visually different: we got rid of the colons and went back to the comfortable quotation marks. They look the same but behave differently. Like Symbols in Ruby, Strings also have a special constructor. Instead of doing:

String.new(”category”)

We just do:

“category”

One could call these kind of shortcuts as “eye-candy”, but the languages would be pretty harsh without them. We use Strings all the time, and it would be extremely painful to instantiate new Strings without this special constructor: simply writing it between quotation marks.

The problem is, as Strings are easy to write, we overuse them more often than not. There is an important side-effect: each new construct instantiates a brand new object in memory, even though they have the same content. For instance:

>> “category”.object_id
=> 2953810

>> “category”.object_id
=> 2951340

Here, we instantiate two strings with the same content. Each object in memory has a unique ID so each string created above uses a separate memory slot and have separate IDs. Now imagine that the same string shows up in hundreds of different places throughout your project. You’re definitely using more memory than necessary.

But, this is not a new problem. For that, we have another construct in most languages called ‘constants’, Ruby included. We have to conscientiously plan and pre-define several constants beforehand. So, that’s how our previous example would be using memory efficient constants:

class Transact < ActiveRecord::Base
  ACCOUNT = "account"
  CATEGORY = "category"
  VALUE = "value"
  WHEN = "when"

  validates_presence_of WHEN
  validates_presence_of CATEGORY, ACCOUNT
  validates_presence_of VALUE
  validates_numericality_of VALUE

  belongs_to CATEGORY
  belongs_to ACCOUNT
end

This works, but this is not nearly as nice. First of all, you have to pre-define everything beforehand, either in the same class or a separated module just for constants. Second, the code is less elegant, less readable, thus, less maintainable.

So, we get back to the purpose of Symbols: being as memory efficient as constants but as easy to the eyes as full fledged strings. Quotation mark notation is already taken for Strings, capitalized words for constants, dollar sign for global variables and so on. So, colon was a good candidate.

Let’s see what it all means:

>> “string”.object_id
=> 3001850
>> “string”.object_id
=> 2999540

>> :string.object_id
=> 69618
>> :string.object_id
=> 69618

As we explained before, the first two strings have the same content and look similar, but they do occupy different memory slots, allowing for unnecessary duplication.

The last two symbols both are exactly the same thing. So I can call identifiers as symbols through all my code without worrying about duplication in memory. They are easy to initialize and easy to manage.

We can also transform a String into a Symbol and vice-versa:

>> “string”.to_sym
=> :string
>> :symbol.to_s
=> “symbol”

One good place where this is put to good use is within Rails’ ActiveSupport. This package was made to extend the Ruby language, and one such extension was made to the ubiquitous Hash class. Let’s see an example:

>> params = { “id” => 1, “action” => “show” }
=> {”action”=>”show”, “id”=>1}

>> params["id"]
=> 1

>> params.symbolize_keys!
=> {:id=>1, :action=>”show”}

>> params[:id]
=> 1

The first statement instantiates and populates a Hash (yet another special initialization notation). The second statement asks for the value identified by the key “id”, which is a string.

Instead of doing it this way, we can call the symbolize_keys! to transform all string keys into symbol keys. Now in the last statement we can use the more usual Rails notation as symbol keys within a Hash. When Rails receives a HTML Form post request, it only gets strings, so it is its job to convert everything into meaningful Rails objects. If you’ve been in the Rails world, you already saw this usage with controllers.

So, this is all to be said about Symbols: very simple constructs that makes code more readable and more efficient at the same time, which is compatible with the Ruby Way.

Thank you Fabio for showing us a different perspective on Symbols. In case you have any queries, questions on this article, kindly post your questions here and Fabio would be glad to answer.

Technorati Tags: , , ,

Posted by Satish Talim



Ruby Quirks

Wednesday 11 April 2007 @ 8:40 am

Ruby Quirks - peculiarity of behavior? I know this topic is debatable and remember ‘one man’s meat is another man’s poison!

I plan to write down here (in no particular order), some of the little Ruby quirks that I’ve picked up and which, I now use comfortably.

1. Peter Cooper, the author of the book ‘Beginning Ruby’ introduced me to Real-Time chat using an IRC client. On the #ruby channel at irc://irc.freenode.net/ I heard of this quirk:

class MotorCycle
  def initialize(make, color)
    @make, @color = make, color
  end
end

m = MotorCycle.new('Honda', 'blue')
m.instance_variable_set(:@make, 'Kawasaki')
m.instance_variable_set(:@gears, 4)
puts m.inspect

Check the output of the above program. In the code above:

m.instance_variable_set(:@gears, 4)

sets the instance variable names by symbol to object, thereby frustrating the efforts of the class’s author to attempt to provide proper encapsulation. The variable did not have to exist prior to this call.
Update: Hal Fulton in his excellent book ‘The Ruby Way’ has this to say about instance_variable_set:

It’s true these methods are powerful and potentially dangerous. They should be used cautiously, not casually. But it’s impossible to say whether encapsulation is violated without looking at how these tools are used. If they are used intentionally as part of a good design, then all is well. If they are used to violate the design, or to circumvent a bad design, then all is not well.

2. This one is not really a quirk but appears to be one, especially for people coming from a Java background. Last year, Shashank Date gave the PuneRuby members a presentation on ‘Why Ruby Shines’ and three points stood out - ‘Expressions everywhere’, ‘Active Class Definitions’ and ‘Everything is an Object’.

Expressions everywhere - In Ruby, everything returns some value. Therefore a class definition is an expression and one can say something like:

c = class C
end

The value of c is nil.

Active Class Definitions - Look at the following program:

class C
  puts 'In class C'
end

When this class is read the first time, it executes puts and the output is - ‘In class C’.

Everything is an Object - After being with Java since 1995, the concept that classes in Ruby are first-class objects, is hard to digest at first - each is an instance of class Class. When a new class is defined (typically using class Name … end), an object of type Class is created and assigned to a constant (Name. in this case). Hal Fulton’s suggests a mantra to be recited everyday - “Class is an object, and Object is a class.”

3. If I want to swap two variables, I would normally use an additional temporary variable. In Ruby, this is not necessary:

x, y = y, x

will interchange the values of x and y.

4. Jaaron, a reader of this Learning Ruby Blog has this quirk for us. This one is well known and is the cause of much frustration.

x = 7
[1,2,3].each do |x|
end

If the name of a block parameter conflicts with the name of a local variable, the behavior is to assign the local variable to the argument. In this case, the local variable x gets assigned the value 1, then the value 2, then the value 3. The value 7 is lost.
Update (13th April): Matt Chen, Matthew King and Ara Vartanian have commented on this behavior. If you refer to Programming Ruby Second Edition eBook (page 100) it says:

The whole issue with variable scope and blocks is one that generates considerable discussion in the Ruby community. The current scheme has definite problems (particularly when variables are unexpectedly aliased inside blocks), but at the same time no one has managed to come up with something that’s both better and acceptable to the wider community. Matz is promising changes in Ruby 2.0.

5. Are instance variables inherited by a sub-class? David Black the author of Ruby for Rails has this to say: Instance variables are per-object, not per-class, and they’re not inherited. But if a method uses one, and that method is available to subclasses, then it will still use the variable — but “the variable” in the sense of one per object. See the following program:

class C
  def initialize
    @n = 100
  end

  def increase_n
    @n *= 20
  end
end

class D < C
  def show_n
    puts "n is #{@n}"
  end
end

d = D.new
d.increase_n
d.show_n

The output is:

>ruby p049instvarinherit.rb
n is 2000
>Exit code: 0

6. Morgan Schweers, a reader of this blog has this quirk for us. Imagine for a moment, that you want to be able to set a variable, but if it’s not set, you default to a known value. You’d rather do it on a single line.

One of my co-workers tried this:

expand = defined?( expand ) ? expand : true

but ‘expand’ is *defined* by being on the left hand side, BEFORE the RHS is evaluated, so defined? returns true, but because expand hasn’t got a value yet, it returns nil.

I tried:

expand = true unless defined?(expand)

and it doesn’t help either, which really shocked me. I always believed that the postfix-conditional was evaluated before even beginning to evaluate the operation, but I was distinctly disabused of this notion by testing.

Note that ‘expand?’ operator returns nil if its argument (which can be an arbitrary expression) is not defined; otherwise it returns a description of that argument.

I don’t understand the reason for the behavior, and I think it’s a bug, but I’d love to know a good language reason for it.

I am sure that you would have noticed many other Ruby Quirks. I’d definitely like to hear and add them here.


Information

Ruby is an open source thorough language of utmost balance with combination of Perl, Smalltalk, Lisp, Ada and Eiffel. With the recent developments in this language, most developers use this language in the middle tier. Today is the era of developing online business applications, mobile software and its applications. Most developers deploy their online applications after getting business web hosting and then they market for these projects through affiliate marketing campaigns or if they do not want to sell their project they can use ppc advertising for earning some revenue or can offer ppc management programs. When they are in the process of development usually they register domain and use domain parking facility, so that once their project is ready they can instantly put it on the internet.


Technorati Tags:

Posted by Satish Talim



Your favourite bit of Ruby code?

Friday 9 February 2007 @ 11:34 am

An interesting thread at Ruby_talk is ‘Your favorite bit of Ruby code.’


Setting aside time for learning HTML is beneficial to any web host.


John Carter
from New Zealand has this interesting snippet of code:

# Ruby is Objects all the way down and open for extension...
class Integer
  def factorial
    return 1 if self <= 1
    self * (self-1).factorial
  end
end

puts 6.factorial

Technorati Tags:

Posted by Satish Talim



Convert bytes to megabytes

Tuesday 6 February 2007 @ 11:26 am

In one of my projects, I need to find the file-size in megabytes again and again. This simple method helps me to convert the size of a file in bytes to megabytes. This is useful for very large files.

MEGABYTE = 1024.0 * 1024.0
def bytesToMeg bytes
  bytes /  MEGABYTE
end

# big file
len = File.size("Dreamweaver8-en.exe")
puts len.to_s + ' bytes'  # displays 62651176 bytes
puts bytesToMeg(len).to_s + ' MB'  # displays 59.7488174438477 MB

One of the uses for PDF conversion is that by going through the process of converting PDF to Word you’ll have a more easily editable document than if you didn’t do PDF conversion and tried to edit a PDF file.

The program code is pretty obvious and as you can see the method uses division. However, it is best to wrap this functionality in a method.

Technorati Tags: ,

Posted by Satish Talim




RUBYGALORE.COM