Friday, May 2, 2008

Using Symbols

If you all are anything like me, symbols confuse the hell out of you. You may use them, but you don't really understand them. I decided to research it out a little today and see what I could figure out. It turns out that there are a lot of different viewpoints of symbols out there. Here are some articles I came across:



The first is a detailed overview of symbols, the second shows some of the way Rails uses symbols.


So, as a quick summary, here is what I know about symbols:
A symbol is used to represent strings, without the overhead of actually creating a string. They don't have the functionality that you get with a string, and the value of them can't be changed, but they are much more efficient than using a string. Here is part of the example from the Gluttonous article:



> patient1 = { "ruby" => "red" }
> patient2 = { "ruby" => "programming" }
> patient1.each_key {|key| puts key.object_id.to_s}
211006
> patient2.each_key {|key| puts key.object_id.to_s}
203536

The key in both hashes creates(string "ruby") has a string object created each time. So, in this example, we have 2 seperate string objects with the same name. You can achieve the same result with symbols:



> patient1 = { :ruby => "red" }
> patient2 = { :ruby => "programming" }
> patient1.each_key {|key| puts key.object_id.to_s}
3918094
> patient2.each_key {|key| puts key.object_id.to_s}
3918094

The difference here is that the same symbol is referenced in both of these. Not only is symbol a smaller object, but it gets reused.


So I am curious, what ways do you all use symbols?



-Ralph

Thursday, May 1, 2008

Intro to the Rails Console

Hi all. Today I'm going to give you a bit of an introduction to the Rails console. Using it will make your life a lot easier. To open it up, type ./script/console from your project directory. From here you can play around, test out commands, add objects to the database if you haven't created an page to do it yet. I'll be using the console from my Forum tutorial to give you examples, so here we go!


First, let's load all of our topics from the database into a variable:



>> @topics = Topic.find(:all)

Which outputs the following:



=> [#<Topic id: 1, forum_id: 1, user_id: nil,
subject: "My Rails 2.0 Forum Tutorial",
body: "Check it out, http://railsonedge.blogspot.com",
created_at: "2008-03-06 11:11:07",
updated_at: "2008-03-06 11:11:07">,
#<Topic id: 2,
.......

Easy stuff. Now lets take that hash, and make it into something useful:



y @topics

The 'y' function outputs everything in yaml format, much more readable:



---
- !ruby/object:Topic
attributes:
updated_at: 2008-03-06 11:11:07
body: Check it out, http://railsonedge.blogspot.com
subject: My Rails 2.0 Forum Tutorial
id: "1"
forum_id: "1"
user_id:
created_at: 2008-03-06 11:11:07
attributes_cache: {}

- !ruby/object:Topic
attributes:
updated_at: 2008-03-06 11:11:37
body: Check it out! http://railsonedge.blogspot.com
subject: New Blog Post Today!!
id: "2"
forum_id: "1"
user_id:
created_at: 2008-03-06 11:11:37
attributes_cache: {}

- !ruby/object:Topic
attributes:
updated_at: 2008-03-09 00:35:44
body: Welcome to the new forum.
subject: Welcome!
id: "3"
forum_id: "2"
user_id:
created_at: 2008-03-09 00:35:44
attributes_cache: {}

- !ruby/object:Topic
attributes:
updated_at: 2008-03-09 00:36:04
body: What time is it?
subject: "Question:"
id: "4"
forum_id: "2"
user_id:
created_at: 2008-03-09 00:36:04
attributes_cache: {}

Now, lets grab just one of the topics and play around with that:



@topic = Topic.find(1)

You can use the 'y' function on this also. Try this to display certain attributes of @topic:



>> @topic.body
=> "Check it out, http://railsonedge.blogspot.com"

And you can change these attributes pretty easily also:



>> @topic.body = "And now the body says this."
=> "And now the body says this."
>> @topic.body
=> "And now the body says this."

When you change an attribute, it doesn't automatically save it to the database. But not to worry, it is easy enough:



>> @topic.save
=> true

Additionally, if you are working on a project and don't have a create page set up yet for an object yet, you can just create one from the console:



>> topic = Topic.new :body => "Lorem Ipsum",
:subject => "This Subject", :forum_id => 1, :user_id => 1
=> #<Topic id: nil, forum_id: 1, user_id: 1,
subject: "This Subject", body: "Lorem Ipsum",
created_at: nil, updated_at: nil>
>> topic.save
=> true

That is enough for some basic manipulation of things in your database, but what other things can you do with the console? What if you wanted to see all of the functions that can be used on a specific object? Well, just like when you are using bash, you can use tab to auto-complete:



String.to_ [press tab not enter]

String.to_a String.to_s
String.to_enum String.to_yaml
String.to_json String.to_yaml_properties
String.to_param String.to_yaml_style
String.to_query

Another good thing to use the rails console for is to test out little bits of code to see how they run. Here is a simple example using a loop in the console:



>>@topics = Topic.find(:all)
>> for topic in @topics do
?> puts topic.subject + " - append this"
>> end

My Rails 2.0 Forum Tutorial - append this
New Blog Post Today!! - append this
Welcome! - append this
Question: - append this

As with most terminals, you can access your command history by using the up arrow.
Another cool thing, when you are messing around with routing, you can check things out quickly with app.url_for and app.get:



>> app.url_for(:controller => 'forums', :action => 'index')
=> "http://www.example.com/forums"

>> app.get '/forums/1/topics'
=> 200

>> app.get '/invalid/url'
=> 404


The underscore('_') character will return the value of the last statement:



>> 5 + 9
=> 14
>> _
=> 14
>> _ + 6
=> 20
>> _
=> 20

Well, that is it for now. Let me know what other uses you guys (and girls?) have for the console.


Later,


-Ralph