What’s special about Ruby?

Well let’s start with a few stand-out thoughts on Ruby:

  • Ruby is an object of beauty –> inspired & passionate developers
  • It’s elegant and concise –> a joy to work with
  • Easy to learn but very powerful –> more experienced developers
  • Is designed for programmer happiness –> all of the above

 
Before I go further, I should warn you that these are just my personal thoughts. I’m no programming guru (and relatively new to Ruby.) But, like countless others, I’ve fallen head-over-heels in lurrve with it and am extremely passionate about it (can you tell?)

Why Ruby?

So why would someone choose Ruby over any other language? Well I can’t speak for everyone else, but I can tell you why I turned to it.

In a nutshell, it felt like the closest thing we have to how a language should be written. In other words, it’s the best programming language out there. Let me rephrase that again. Ruby is the only language I came across that ticked most if not all the boxes for my requirements: it’s powerful, easy to learn, has a huge set of libraries, a vibrant community, the best web framework, and (as an unexpected bonus) is a genuine pleasure to use. Ruby was designed specifically with Programmer Happiness™ in mind. If you don’t believe me, ask its creator, Matz.

Why not Python/PHP/Java/[insert other language here]?

I think it’s important to quickly mention two of the main reasons why I think other languages fall short:

  • They are a pita to use (semicolons after every line/poor object models/ill-thought method names/using camelCaseForVariables, etc)
  • Or they just don’t have the same appeal – that something special – that Ruby does.
  • (or both)

I found Ruby because other languages either drove me away through their idiosyncrasies, convoluted or awkward ways, or because they just didn’t posses the special qualities that makes Ruby stand out. Qualities such as the best web framework (Ruby on Rails), a huge set of libraries, a vibrant community, etc. (As detailed above in ‘Why Ruby?’)

I wasn’t going to talk about other languages too much, but a few people have asked for code comparisons, so here they are. (Python code provided by @excid3, PHP code by @citalan.)

PHP

class Ball
{
    private $_colour;

        public function __construct($colour)
    {
        $this->_colour = $colour;
    }

        public function is_red()
    {
        return ($this->_colour == 'red' ? true : false);       
    }
}

$the_ball = new Ball('green');
echo ($the_ball->is_red() ? '' : 'The ball is not red');

Python

class Ball:
    def __init__(self, colour):
        self.colour = colour

            def is_red(self):
        return self.colour == "red"

        the_ball = Ball("green")

if not the_ball.is_red():
    print "The ball is not red"

Ruby

class Ball
  def initialize(colour)
    @colour = colour    
  end

    def is_red?
    @colour == "red"
  end
end

the_ball = Ball.new("green")
puts "The ball is not red" unless the_ball.is_red?

Notice how clear and concise the Ruby code is? At a glance you quickly see what’s going on – the do ends provide excellent visual boundaries. Not too bare (like Python) but not convoluted like PHPs endless semicolons and brackets either. It strikes the perfect balance. If you really wanted to, you could even write the same code like this:

class Ball
  def initialize(colour); @colour = colour; end
  def is_red?; @colour == "red"; end
end

the_ball = Ball.new("green")
puts "The ball is not red" unless the_ball.is_red?

or even like this – without parentheses:

class Ball
  def initialize colour; @colour = colour; end
  def is_red?; @colour == "red"; end
end

the_ball = Ball.new "green"
puts "The ball is not red" unless the_ball.is_red?

Most people stick with the original tho – perhaps without parentheses when it’s more appropriate (such as when using Rails or DSLs).

So what is special about Ruby?

Oh boy, where do I start? It’s clean, uncluttered and has an air of grace and elegance. No trailing semicolons. No need for parentheses for method calls (or definitions) …even hashes don’t need them if they’re the last argument in a call. Ruby is just so refreshing.

Once you get past how gorgeous Ruby code looks, you begin to read it. Ruby’s syntax is clear and concise, and there’s nearly always more than one way of doing something. These nuances matter because they give the language a natural feel – when you read Ruby, it reads better, moreso than what you might be used to in other languages.

Ok so maybe you think all that’s superficial (for the record… it’s not!) but either way – there’s a lot more going on under the hood.

Ruby is a ‘proper’ object orientated language. In fact, almost everything in Ruby is an object. Even classes (being an instance of the class Class.) Each object belongs to the class it was instantiated from, and… it even has it’s very own class, an Eigenclass (sometimes called the Singleton class). This is cool because it means individual objects, can truly be, er, individual! (You can give objects methods that other objects of the same class don’t have.)

You can ‘mix-in’ modules into your classes. Modules are like classes (actually, classes are descended from modules) with the main difference being that you can’t instantiate an object directly from them. A class can include as many modules as you want it to, so they are a great way to organise your code and share functionality between classes. They’re also handy for namespacing (so your class names are less likely to clash with someone else’s).

Ruby also gives us open classes, where you can reopen a class at any point and just add to it. You can even do this to standard classes, such as the String class – how many languages let you do that huh!? You could actually go on to modify existing code. Don’t like how a method works? No problem, change it! This is often referred to as monkey patching – something that often scares people from other languages. But that’s Ruby – it treats you as a grown-up, and lets you decide how responsible (or ruthless!) you want to be.

Ruby also gives us code blocks which are great for (amongst other things – such as DSL’s) closures – although we also get bindings for that. Duck typing means we don’t have to declare types beforehand and syntactic sugar lets us create setter methods like this:

def name=(x)
 name = x
end

Where ‘name=’ is the name of the method. Remember that parentheses are optional in Ruby? Well that, and the fact that Ruby lets us use an equals sign in our methods (as shown above) allows us to go on and do this:

name = "AstonJ"

It ignores the space between the equals sign and the rest of the method. Pretty cool, no? And that’s just scratching the surface – there’s loads more on offer!

Ruby also gives us powerful tools and tricks like introspection, dynamic methods, ghost methods, mimic methods, class macros and the creation of classes, methods and other code on-the-fly – something you might have heard of as metaprogramming: code that writes code. We also get proc objects (in a number of flavours) and all the usual stuff you’d expect, such as Arrays, Strings, Hashes, and a lot of others you might not, like method missing, class eval, bang methods and more! And that’s just the language itself!

The community

Here I’ll just copy and paste what I wrote in a previous post (What’s special about Ruby on Rails) as pretty much the same applies here.

The Ruby community rocks. You get the feeling everyone is on the same wavelength, most Rails devs seem to use OS X and TextMate for example (even down to the same ‘theme’!) but the conventions run a lot deeper. Whether it’s indentation style or using parentheses in your method definitions or calls (they’re optional in Ruby) there’s a ‘Ruby way’ and most in the community stick to it. It’s not because Ruby users are mindless zombies mind you, it’s because we genuinely like the same things and have similarly high standards.

The most important thing however, is how passionate and helpful the community is. Good enough just isn’t good enough. That’s why test driven development (TDD) is such a big thing in the Ruby community, and why you can rest assured that your peers will always help you stay on top of your game.

As you might expect, with something so cherished at its heart, the community are eager to help each other get the best out of it. Testament to this are all the resources that are not only free but have clearly taken a lot of time and effort to put together. Here’s a quick list:

  • tryruby.org – where you get to try (and learn) Ruby in your browser
  • the extremely enjoyable Rails for Zombies where the Envy Labs team take you through some gory screencasts then test your knowledge via the brain browser
  • the fantastic Railscasts which is nearly as old as Rails itself (!)
  • Rails Tutorial which is an excellent step-by-step that helps you build a twitter clone.
  • the IRC #rubyonrails channel (irc.freenode.net) where there’s always some cheery soul willing to lend a helping hand
  • the utterly brilliant Ruby Mendicant University (and Ruby Best Practices from the same person, Gregory Brown).
  • Finally I just have to include Rails Hotline where if you get stuck and fancy talking to someone who might be able to help, you can – for free!

Pretty awesome don’t you think? And did I mention they are all free!?

If all of that isn’t enough for you (it should be, but if it isn’t…) then there’s one last thing that I find quite remarkable. I’m fairly new to Ruby, yet many leading or well known figures in the community have taken time out to speak to me. Yehuda Katz talked to me at length about learning Rails. Gregg Pollack was happy to discuss my ideas of where Rails for Zombies could lead. Ryan Bigg made the effort to get a .mobi version of his book (Rails 3 in Action) to me as he was keen on hearing my thoughts, and even DHH (the creator of Rails) has discussed totally unrelated topics via Twitter. And that’s just the people who I know of who are leading figures! I’ve also exchanged tweets with a number of others but won’t include them here for brevity – well apart from Russ Olsen, the author of two of my favourite Ruby books (Design Patterns in Ruby and Eloquent Ruby) who is following me on Twitter. *Faints

It’s fantastic that a large number of people high up in the community are willing to take time out for the nubes. Is there any wonder why the community is as cool as it is?

I’d quickly like to add that the community isn’t just about programmers – many Ruby related businesses are very much part of it too. Companies like Engine Yard, Heroku, 37 signals, Shopify, Envy labs, Thoughtbot, Resolve Digital and countless others who give so much back. Just recently for example, Heroku have taken on Matz (the creator of Ruby) to work on Ruby full time – how brilliant is that!?

Culture

I want to cover culture on its own, because not all of it comes from the community. Of course the Ruby community will push you towards test driven development, writing good clean idiomatic code, contributing back to Ruby or other open source projects and generally helping you become a good Ruby citizen. But some cultural aspects are inherently down to the language itself – bizarre as that might sound.

The most important, and perhaps what will (and should?) make for interesting reading for managers and the ‘enterprise’, is the culture of learning.

If you go back to my list at the start of this post, you’ll see the brief list of things that make for Ruby Programmer Happiness™ – and what do people excel at? Things they enjoy :-)

I noticed a massive difference in my desire to learn Ruby, compared to PHP. PHP totally uninspired me. Don’t get me wrong, I was as desperate to learn to program as much as I’ve ever been (maybe even moreso back then) but all I wanted to do was get through the PHP books as quickly as possible just to ‘get on with it’. I never really enjoyed PHP, therefore I didn’t enjoy learning it – and that’s a problem, because people will generally only do the minimum or just skim over stuff, never truly understanding things.

Ruby, by contrast, is something I love. I enjoy reading about it and learning as much as I can. My appetite for all things Ruby is insatiable – and I’m not exactly a geek! It is just constantly, pleasantly, surprising me, and things just seem to ‘stick’ more (that’s testament to Matz wanting to make it a ‘natural’ language) so morale is always high. Additionally, because Ruby is very natural and therefore easy to pick up, you get people from all walks of life giving it a go – and that’s brilliant because it brings in creative people that might have otherwise not got into programming at all.

This, I think, is why you get better Ruby programmers. Of a higher skill-set and with more ‘experience’ – we tend to enjoy furthering our knowledge because we enjoy the topic so much. I really can’t stress this point enough, this is the reason (which itself is only there because of all the other factors) why I believe Ruby is going to grow at a phenomenal rate – it’s because we want to, not because we have to (JS/browsers) or we’re told we should do (Java/enterprise).

Everything else

There’s so much more to cover that it would be impossible to cover everything, so I’ll try to keep this brief. Ruby on Rails is widely considered to be the best web framework (see: What’s Special about Ruby on Rails? for more info) – it’s actually what first drew me to Ruby, and like many people, “I came for Rails but stayed for Ruby”! That’s not the only web framework btw, we also have Sinatra and a heap of others too (and also plenty of CMS and blog systems).

There has been over 281 million downloads of around 28 thousand RubyGems (aka libraries). From testing frameworks to web frameworks to authentication systems to backup systems to geocoding tools to e-commerce to email processing – chances are if you’re trying to do something there’s a gem out there that does it!

We also have lots of great learning material – what good is all that power if you’re just not able to learn it effectively? And lots of companies (like Engine Yard) offer sponsorships for training courses (or there’s even the Ruby University which I mentioned earlier).

Hopefully you’re beginning to get an idea why Ruby is special (and there’s a lot I haven’t even covered – such as the various Ruby implementations, like Jruby, Rubinious, MacRuby). Along with the beauty of language itself, we have all these other things – and they all add up to make Ruby the first class package that it is.

Conclusion

A programming language that inspires people is rather special – and Ruby is one that truly does just that. Add in its power, simplicity and elegance and you have a compelling package. One that will help you in work and play – and often blur the line between the two. Wouldn’t you want to get paid to do something you enjoy? I’m not kidding when I say that’s exactly how it is for almost all Rubyists I know – yet another reason why Ruby is special, for you, your boss, your client, and maybe even the world. (Well maybe!)

Where next?

So have I convinced you? If so keep an eye out for an upcoming post (Edit: link added…) where I’ll detail the best way to learn Ruby (& Rails) - but until then, be sure to check out the following

  • If you’re new to programming, I urge you to go through Learn to Program by Chris Pine – it’s a lovely introduction to OOP and Ruby.
  • If you have some programming experience, then do the excellent Kevin Skoglund Ruby course over at Lynda.com – they are in perfect 5 to 10 minute clips and Kevin really knows his stuff… and knows how to get you to know it!
  • After that, check out David A. Black’s The Well Grounded Rubyist – one of my all-time favourite Ruby books. David is a real-life teacher, and it shows. He takes nothing for granted and walks you through every bit of code in the book so you never feel like giving up.
  • And after that, get Russ Olsen’s Eloquent Ruby – another firm favourite. Russ is a very experienced programmer of a number of different langauges and he really helps you understand the ‘Ruby way’. When I read this book, I used the highlight function on my Kindle so much that in the end I thought ‘forget that – I might as well re-read the book later’ because I am pretty much highlighting it all anyway!

Don’t forget, keep an eye out for my How to Learn Ruby & Rails post – doing everything I list there will help you become fairly proficient in next to no time.

Good luck – and I hope to welcome you into the Ruby community soon!

Source : http://astonj.com/tech/whats-special-about-ruby/

 

LineCache - A module to read and cache file information of a Ruby program

== SYNOPSIS

The LineCache module allows one to get any line from any file, caching
the lines and file information on first access to the file. Although
the file may be any file, the common use is when the file is a Ruby
script since parsing of the file is done to figure out where the
statement boundaries are.

The routines here may be is useful when a small random sets of lines
are read from a single file, in particular in a debugger to show
source lines.

== Summary

  require 'linecache'
  lines = LineCache::getlines('/tmp/myruby.rb')
  # The following lines have same effect as the above.
  $: << '/tmp'
  Dir.chdir('/tmp') {lines = LineCache::getlines('myruby.rb')

  line = LineCache::getline('/tmp/myruby.rb', 6)
  # Note lines[6] == line (if /tmp/myruby.rb has 6 lines)

  LineCache::clear_file_cache
  LineCache::clear_file_cache('/tmp/myruby.rb')
  LineCache::update_cache   # Check for modifications of all cached files.

== Credits

  This is a port of the module of the same name from the Python distribution.

  The idea for how TraceLineNumbers works, and some code was taken
  from ParseTree by Ryan Davis.

== Other stuff

Author::   Rocky Bernstein <rockyb@rubyforge.net>
License::  Copyright (c) 2007, 2008 Rocky Bernstein
           Released under the GNU GPL 2 license

== Warranty

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

$Id$Source : https://github.com/mark-moseley/linecache

Creating More Using Less Effort with Ruby on Rails

 

Creating More Using Less Effort with Ruby on Rails

If you build websites, you have no doubt heard about Ruby on Rails (RoR). But if you’re a designer or front-end developer or you’re using PHP without any application framework, it may seem like a big leap to adopt the Ruby on Rails approach. In this article, I hope to demystify Ruby on Rails and convince you that you can make the leap—and that it is a leap worth making if your needs fit within the Ruby on Rails “sweet spot” detailed below.

It does take time to learn new ways to do all the things you already know how to do, and to learn some new concepts and techniques at the same time. In the short term, switching technologies, even to Ruby on Rails, will destroy your productivity. Nevertheless, I’m convinced that many web developers would be more productive, produce better sites, and even have more fun if they took the leap and began using Ruby on Rails.

Fun for the whole family

Ruby on Rails (Rails for short) is a “full-stack” framework, which means that it covers both front-end and back-end design. This makes it an exceptionally potent tool in the hands of a “jack-of-all-trades” developer. Even if you’re primarily a front-end or a back-end developer, though, you can still use Ruby on Rails effectively. The interfaces between the front end (the browser’s HTML, CSS, and JavaScript) and the back end (Ruby, and the Rails framework) are well defined, so you don’t need to understand both sides if you want to focus on one or the other.

If you’re a web designer or front-end developer, you can learn how to use the Ruby on Rails template system, and how to write little bits of embedded Ruby code in your view files. This will make you a much better partner for a back-end developer, since you can work directly on the Rails application files instead of delivering HTML and CSS that someone else has to integrate.

So whether you’re approaching Ruby on Rails as a front-end or back-end developer, on which projects should you consider using it?

The “sweet spot”

Ruby on Rails is at the heart of diverse web applications and sites such as Basecamp, Blinksale, 43Things, Odeo, Revolution Health, Twitter, YellowPages.com, and A List Apart. The enthusiasm for Rails extends to many of the largest web companies. Yahoo, eBay, Amazon, and AOL all have Ruby on Rails projects, and ThoughtWorks is creating enterprise applications in Rails. But for all the diversity of Ruby on Rails applications, the ones that are best-suited to the framework have a few key things in common.

A website or web service is most appropriately implemented with Ruby on Rails when it has the following three characteristics:

  • It is a database-backed website or web service large enough to justify the overhead of a powerful framework.
  • It has unique needs that aren’t well met by a typical CMS. (If Joomla or Drupal does everything you need, such systems may be a better choice.)
  • It is a new application, allowing developers to start fresh with the database and software architecture.

This is the “sweet spot” for Ruby on Rails applications. Applications that share these characteristics can probably be built much more quickly with RoR than with PHP, .NET, or Java, once the investment required to learn Rails has been made.

Productivity boosts

One of the main reasons Ruby on Rails increases productivity is that it makes building new applications, adding features, and making tweaks much easier. The combination of the language (Ruby) and the framework (Rails) means you can do more with less code. Less code--and better-structured code--means changes are relatively painless, so you can iterate and experiment more readily. This leads to better sites, and, hopefully, more fun building them.

Of course, adopting a major new tool requires an investment of time that can’t be taken lightly. If you’re focused on a single project, it often isn’t justifiable. But if you expect to keep building websites for some time, and you’re building sites of significant complexity, a short-term investment in learning Ruby on Rails will pay off in the long term.

To understand why I believe you can do more with less effort using Ruby on Rails, let’s start with a quick look at Ruby.

Meet Ruby

Ruby is a modern, object-oriented language. In any Ruby program, everything is an object. Ruby is also a dynamic language, which means a variety of things:

  • Ruby is interpreted dynamically (like PHP), so there is no compilation (as there is with C or Java.) This speeds up iterative development.
  • In Ruby, variables are dynamically assigned a type when they are used, eliminating all the code you must write in most other languages to define and set up variables.
  • A Ruby program can generate code dynamically, modifying itself as it executes. Rails uses this capability internally to deliver its “magic,” which you can simply enjoy. (You don’t need to understand how these techniques work.)

Ruby is a wonderfully clean language to read and write, but its benefits go beyond that. Because Ruby can be powerfully extended, the Rails framework is able to turn it into a sort of special-purpose language for building web applications.

While Ruby (a language) and Rails (a framework) are separate things, they complement and depend on each other in many ways. All Ruby on Rails applications are written in Ruby, and the character of Ruby has a big influence on Ruby on Rails applications. There are frameworks, such as CakePHP, that bring many of Rails’ ideas to other languages. But the power and flexibility of Ruby makes Rails cleaner and more flexible than many other frameworks. If you’re going to make the investment in learning a framework, learning Ruby while you’re at it isn’t that big a hurdle, and the payoff is considerable.

The Rails approach

Many websites are built without any application framework at all: you just write the code you need and borrow bits from various places when you can. That’s fine for small sites, but it can quickly get out of control, resulting in reams of messy code that is hard to understand and to maintain.

With a framework such as Ruby on Rails, a lot of decisions about how to structure your code are already made for you and you also have a powerful set of libraries at your disposal.

Another important characteristic of Rails is that it organizes each application around a model-view-controller (MVC) structure. MVC, a well-established pattern for organizing software projects, gives all your code a consistent structure, which helps a lot when you’re working on multiple sites, or bringing in someone new to work on a site. It also provides separate files, with clean interfaces, that can be split between front-end and back-end developers.

Databases and objects

Ruby on Rails is designed to be used to build database-backed applications, and many of its core components focus on interacting with databases. The heart of Rails is a library called Active Record, which implements something called object-relational mapping (ORM). With ORM, you can work with software objects that represent your data and let the Active Record library take care of communicating with the database.

This may sound mysterious in the abstract, so let’s make it concrete. Even without knowing any Ruby--or anything about object-oriented programming--I bet you can make sense out of the following code examples, which are pieces of actual Ruby on Rails code.

Suppose you have a bookstore site and you want to add a new book. You could write:

newbook = Book.new

You’re telling the “Book” class that you want an empty book object, named “newbook.” You can set the title, or any of its other attributes, in an intuitive way:

newbook.title = "Angle of Repose"
newbook.author = "Wallace Stegner"

At this point, you have an object in memory. All it takes is:

newbook.save

...and your new book has been written to the database. Active Record generates the SQL to tell the database to insert the record. You can add validations on all the fields and generate descriptive error messages with just a few more lines of code.

Now you want to find that book out of the millions in your database. Just write:

angle_of_repose = Book.find_by_title "Angle of Repose"

...and you have an object, which you’ve named “angle_of_repose,” that has all the information from the appropriate database record.

There’s a little more to it, but not that much; working with software objects that reflect the information your site deals with is a natural and powerful approach. In RoR, you have a rich set of software objects that correspond to your database tables, and these objects make up the “model” layer of the model-view-controller system.

Your code interacts with the model objects, and Active Record creates the SQL to make the database do what you want. You don’t have to write any SQL to work with the database. And since none of your code communicates directly with the database, you can switch from one database engine to another by simply changing a configuration setting.

Views and controllers

To create web pages, Rails provides a template system that makes it easy to use consistent page structures, to insert common components without repeating their code, to render information that comes from the database, and to display and process forms. These templates constitute the “view�? layer of the model-view-controller system.

If you’re a front-end developer, this is the part of Rails you should focus on. You can simply assume that your “view file” will be handed variables that contain whatever information you need to display. Just as PHP files are a mix of PHP code and HTML, a typical Rails view is a mix of Ruby and HTML. Continuing with our bookstore example, here’s a snippet of view code that displays the title and author of a book:

 

<%= book.title %>

 

<%= book.author %>

The Ruby code is marked by <%= and %>; the rest is HTML. The HTML and the output of the Ruby code are combined to create the web page.

Rails has integrated support for the Prototype and Scriptaculous JavaScript libraries, plus a great facility called Ruby JavaScript (RJS), for building Ajax interfaces. You can write almost everything in Ruby, including code that is eventually executed by the browser as JavaScript (the Rails framework handles the translation.)

A “controller” is a piece of Ruby code whose primary job is to communicate with the model to prepare the data needed by the view. Any information that the view needs is assembled by the controller in a set of variables before invoking the view. The controller also responds to Ajax requests after the page has loaded. Controllers provide a variety of other functions as well, from user authentication to error handling.

“Convention over Configuration”

Rails tries hard to provide reasonable defaults for almost everything. Following a philosophy called Convention over Configuration, Rails almost entirely eliminates configuration files.

If you follow the Rails conventions, an amazing amount of stuff, from routing requests to the correct controller and view, to validating form data and displaying error messages, just works. Compared with most other languages and frameworks, it takes less code to accomplish most common tasks.

The Convention over Configuration approach is sometimes frustrating for newcomers, especially if they try to learn from an existing application, because there are hidden assumptions behind much of the code. The assumptions are what make the code simpler, but they can be confusing when you don’t know them. After you learn the Rails conventions, though, everything in Rails makes more sense. And when you’re building a new site, you have the wind at your back, because so much is already defined for you.

It’s not perfect

Rails does have its drawbacks. These weak points are minimized for applications that fall within the Rails sweet spot I described earlier, but they can be big issues at the fringes.

Ruby is slower than most other languages. This is likely to change this year, but for now, it is a disadvantage--for those few applications in which processing time is actually an issue. In reality, this is a non-issue for the vast majority of websites.

The overhead of the MVC framework can also slow things down. With a little attention, though, most Rails applications can be made to perform very well. Model requests often need tuning to reduce the number of database accesses required. You can often eliminate database requests entirely: Rails includes a powerful caching system, so pages can frequently be created once and delivered many times.

Rails applications are also more trouble to host than PHP applications. Because of the size of the Rails framework code, it has to be kept in memory all the time, not loaded in response to a request. You need 100–200 MB of dedicated RAM to host even a low-traffic Rails application. With PHP applications, in contrast, you can host hundreds of applications on a single server, because they don’t occupy any memory when they aren’t being accessed.

Because of these server requirements, shared hosting of Rails applications is generally problematic. A VPS (virtual private server) is usually the best choice. Setting up a Rails server can be more complex than for PHP. This was an issue a year or two ago, but now there are many Rails-oriented hosting companies that provide turnkey solutions.

Another result of these server requirements is that Ruby on Rails hosting tends to be more expensive than for other platforms and languages. If you’re in the Rails sweet spot, your application is significant enough that the incremental hosting cost is insignificant compared to the value you get from using Rails.

The learning curve

The complexity of Rails can make it hard for a beginner to get started: it takes months to become familiar with all of Rails. But you can get started by first learning just enough to build a basic Rails site. As you begin working with it, you’ll pick up new skills and knowledge as you need it.

People come to building websites in various ways and from different backgrounds, but most of them fall into one of two categories:

  • People who have an idea for a site they want to build and learn just enough technology to build it.
  • Programmers who see websites as just another kind of program.

Ruby on Rails was built by programmers, for programmers. So if you come to it from a professional software development background, it will feel a lot more familiar than if you come from web design.

If you’re not a software developer, there’s more to learn, but it’s not beyond your reach. Learning the parts of Ruby, and some bits of object-oriented programming, that you need to know to use Rails is not difficult. To start building applications using the Rails framework you only need to know how to use a limited subset of Ruby’s capabilities.

You can leave the advanced Ruby coding to those who work on the framework itself. You don’t need to understand much about how the internals of Rails works, or the techniques (such as metaprogramming) that it uses internally.

The Rails ecosystem includes many practices that come from the software development world, including use of source-code control systems, an automated testing framework, documentation tools, and deployment scripts. If you’ve been doing ad-hoc web development, these may be foreign concepts, but they can bring a lot of sanity into your work life once you become comfortable with them.

What to learn when

The art of learning Rails is figuring out just what you can ignore at which stage of your education so you can grapple with a few things at a time, instead of with all the diverse technologies that make up a Rails application. (One easy way to get started learning Ruby on Rails is with the "free online course":http://www.BuildingWebApps.com/learning_rails produced by the author of this article.)

Start by learning the basics of Ruby. You don’t need to go too deep, but you need to know the basics before you can effectively develop with Rails. Rails code looks almost like markup, and it is tempting to think of it as such, but you need to make the shift to thinking of your site as a program that emits web pages, rather than as a set of files that are web pages.

If you’re focused on the front end, learn how layouts, view templates, and partials work. If you’re working with a back-end developer, they’ll take care of the model and controller layers and provide your views with variables packed with just the data you need.

At first, you can ignore Ajax; it’s a largely separate layer that can make a big improvement in the user experience, but it really is optional. So you can put RJS, Prototype, and Scriptaculous aside when you’re learning Rails. Add on a layer of Ajax sophistication once you’re comfortable with the basics.

If you’re a back-end developer, concentrate on learning how to model your application domain as a set of resources, create your database tables, and use the resulting objects. The Rails framework is wide and deep, so it takes time to learn thoroughly, but you don’t need to use very much of it to get started.

While you’re learning Rails, you can ignore testing and all its associated complexities, even though it gets a lot of attention in discussions of Rails. When you’re further along, come back to it--but don’t let it slow down your initial learning or add to your cognitive load.

And you’re off!

Once you’re up to speed, Ruby on Rails will become an old friend. With this powerful set of tools at your fingertips, you’ll be more productive than ever.

By being able to do more with less code, you’ll build better sites and have more fun doing it. There’s no looking back.

Illustration by Kevin Cornell

Source : http://www.alistapart.com/articles/creatingmoreusinglesseffortwithrubyonrails/

How to Pass Params to Named Scope in Rails

Hi guys :)

In my previous post create named scope in rails, I told you about named scope in rails, what excess of named scope,how to create and how to use it. Now i will tell you, how to pass params to named scope in rails. For example, we will search users by user_name, first_name, last_name, email and city. Most of us, will create in the controller like this :

 

1
2
3
4
5
6
class UsersController < ApplicationController
  def search
      @users = User.where(["user_name LIKE ? OR first_name LIKE ? OR last_name LIKE ? OR email LIKE ? OR city LIKE ?",
      "%#{params[:keyword]}%", "%#{params[:keyword]}%", "%#{params[:keyword]}%", "%#{params[:keyword]}%", "%#{params[:keyword]}%"])
  end
end

 

That’s will work correctly, but that’s not recomended by rails development. I think the best way to do it is to create named scope and pass the params to named scope. Please look below, how to pass params to named scope in rails.

In user model :

1
2
3
4
5
class User < ActiveRecord

   scope :search, lambda{|keyword| where(["user_name LIKE ? OR first_name LIKE ? OR last_name LIKE ? OR email LIKE ? OR city LIKE ?",
      "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%"])}
end

In user controller :

1
2
3
4
5
class UsersController < ApplicationController
  def search
      @users = User.search(params[:keyword])
  end
end

Source : http://whatisrubyonrails.com/how-to-pass-params-to-named-scope-in-rails

How to Create Named Scope in Rails

Named scope used to specify commonly used sql queries which can be define as method on model or on the association objects. With named scope, you can use every that have been included ActiveRecord method such us joins, select, where and etc.

Most of us start out writing our queries directly in the controllers, like this :

1
2
3
4
5
6
class  ArticleController < ApplicationController

  def article_today
    @articles = Article.where(["created_at > ?", Time.now.beginning_of_day])
  end
end

That’s works, but it’s broken cardinal role of Rails development. Rather than we embedding sql query in our controller to find article which created today in our site, much better to write something code called named scope in model which would return a collection of Article objects. To create a scope, we use the named_scope method in Rails 2 and scope method in Raials 3 above inside the class model.

Rails 2 :

1
2
3
4
class Article < ActiveRecord::Base

 named_scope :today, where(["created_at > ?", Time.now.beginning_of_day])
end

Rails 3 above :

1
2
3
4
class Article < ActiveRecord::Base

 scope :today, where(["created_at > ?", Time.now.beginning_of_day])
end

Then in our controller we call :

1
2
3
4
5
calss ArticlesController < ApplicationController
 def article_today
 @articles = Article.today
 end
end

That’s would return a collection of Article objects which created today. It’s look DRY query. In addition we also use scope to get object with join table. Please look below :

Rails 2 :

1
2
3
4
5
class User < ActiveRecord::Base
 has_many :addresses

 named_scope :group_by_city, joins(:addresses).where(["addresses.city = ?", "Jakarta"])
end

Rails 3 above :

1
2
3
4
5
class User < ActiveRecord::Base
 has_many :addresses

 scope :group_by_city, joins(:addresses).where(["addresses.city = ?", "Jakarta"])
end

Source : http://whatisrubyonrails.com/create-named-scope-in-rails

How to Connect to Multiple Database in Rails

I have problem in build rails application that how to connect to multiple database in rails. After I searching i found how to fix my problem in here and in Rails Recipe B3 ebook.

By default Rails have a connection to one database per aplication. But if you want to connect to multiple databse, it’s very simple in rails. To create connection to multiple database in a rails application, we must set up named connection in database configuration(database.yml), configure model, and use inheritance to safely allow multiple models to use the new named connection.

In this case we have scenario like this :

 

connect to multiple database in rails

OK, let’s create a new rails application with mysql databse :

1
rails new multiple_database –database=mysql

In this case I use rails 3.1, but I think this same way in rails 3.0

Configure databse.yml to be like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: multiple_database_development
  pool: 5
  username: root
  password: root
  socket: /var/run/mysqld/mysqld.sock

external_development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: multiple_database_external
  pool: 5
  username: root
  password: root
  socket: /var/run/mysqld/mysqld.sock

Now create database whit this command line :

1
rake db:create:all

Create article and comment model :

1
2
rails g model article title:string content:text
rails g model comment article_id:integer name:string content:text

Open article model, and edit to be like this :

1
2
3
class Article < ActiveRecord::Base
  has_many :comments
end

Open comment model, and edit to be like this :

1
2
3
4
class Comment < ActiveRecord::Base
  establish_connection("external_development") #external_development is a named configuration in database.yml
  belongs_to :article
end

Open create_comment migration file and add this section above def self.up in rails 3.0 or def change in rails 3.1:

1
2
3
def connection
    Comment.connection
end

so it becomes like this :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CreateComments < ActiveRecord::Migration

  def connection
    Comment.connection
  end

  def change
    create_table :comments do |t|
      t.integer :article_id
      t.string :name
      t.text :content

      t.timestamps
    end
  end
end

Note : Comment.connection is a method to determine which database is used in migration as it has been declared in comment model.

Don’t forgate migrate file to database:

1
rake db:migrate

 

Open rails console, and chek connection :

create article

1
article = Article.create(:title => "First Article", :content => "Content of first article")

create comment

1
comment = article.comments.create(:name => "Dan", :content => "this is comment content")

 

Check database connection :

Article Connection

1
Article.connection.current_database

will be return :

1
=> "multiple_database_development"

Comment Connection

1
Comment.connection.current_database

will be return :

1
=> "multiple_database_external"

Now we can see that different database used. Article model use “multiple_database_development” database and comment model use “multiple_database_external” database.

Source : http://whatisrubyonrails.com/how-to-connect-to-multiple-database-in-rails

cocoon

cocoon is a Rails3 gem to allow easier handling of nested forms.

Nested forms are forms that handle nested models and attributes in one form. For example a project with its tasks, an invoice with its ordered items.

It is formbuilder-agnostic, so it works with standard Rails, or Formtastic or simple_form.

Prerequisites

This gem uses jQuery, it is most useful to use this gem in a rails3 project where you are already using jQuery.

Furthermore i would advice you to use either formtastic or simple_form.

I have a sample project where I demonstrate the use of cocoon with formtastic.

Installation

Inside your Gemfile add the following:

gem "cocoon"

Rails 3.1

Add the following to application.js so it compiles to the asset_pipeline

//= require cocoon

Rails 3.x

If you are using Rails 3.0.x, you need to run the installation task (since rails 3.1 this is no longer needed):

rails g cocoon:install

This will install the needed javascript file. Inside your application.html.haml you will need to add below the default javascripts:

= javascript_include_tag :cocoon

or using erb, you write

<%= javascript_include_tag :cocoon %>

That is all you need to do to start using it!

Usage

Suppose you have a model Project:

rails g scaffold Project name:string description:string

and a project has many tasks:

rails g model Task description:string done:boolean project_id:integer

Edit the models to code the relation:

class Project < ActiveRecord::Base
  has_many :tasks
  accepts_nested_attributes_for :tasks, :reject_if => :all_blank, :allow_destroy => true
end

class Task < ActiveRecord::Base
  belongs_to :project
end

What we want to achieve is to get a form where we can add and remove the tasks dynamically. What we need for this, is that the fields for a new/existing task are defined in a partial view called _task_fields.html.

We will show the sample usage with the different possible form-builders.

Using formtastic

Inside our projects/_form partial we then write:

- f.inputs do
  = f.input :name
  = f.input :description
  %h3 Tasks
  #tasks
    = f.semantic_fields_for :tasks do |task|
      = render 'task_fields', :f => task
    .links
      = link_to_add_association 'add task', f, :tasks
  -f.buttons do
    = f.submit 'Save'

and inside the _task_fields partial we write:

.nested-fields
  = f.inputs do
    = f.input :description
    = f.input :done, :as => :boolean
    = link_to_remove_association "remove task", f

That is all there is to it!

There is an example project on github implementing it called cocoon_formtastic_demo.

Using simple_form

This is almost identical to formtastic, instead of writing semantic_fields_for you write simple_fields_for.

There is an example project on github implementing it called cocoon_simple_form_demo.

Using standard rails forms

I will provide a full example (and a sample project) later.

How it works

I define two helper functions:

link_to_add_association

This function will add a link to your markup that will, when clicked, dynamically add a new partial form for the given association. This should be placed below the semantic_fields_for.

It takes four parameters:

  • name: the text to show in the link
  • f: referring to the containing form-object
  • association: the name of the association (plural) of which a new instance needs to be added (symbol or string).
  • html_options: extra html-options (see link_to) There are three extra options that allow to control the placement of the new link-data:
    • data-association-insertion-node : the jquery selector of the node
    • data-association-insertion-method : jquery method that inserts the new data. before, after, append, prepend, etc. Default: before
    • data-association-insertion-position : old method specifying where to insert new data.
      • this setting still works but data-association-insertion-method takes precedence. may be removed in a future version.

Optionally you could also leave out the name and supply a block that is captured to give the name (if you want to do something more complicated).

link_to_remove_association

This function will add a link to your markup that will, when clicked, dynamically remove the surrounding partial form. This should be placed inside the partial _<association-object-singular>_fields.

It takes three parameters:

  • name: the text to show in the link
  • f: referring to the containing form-object
  • html_options: extra html-options (see link_to)

Optionally you could also leave out the name and supply a block that is captured to give the name (if you want to do something more complicated).

Inside the html_options you can add an option :render_options, and the containing hash will be handed down to the form-builder for the inserted form. E.g. especially when using twitter-bootstrap and simple_form together, the simple_fields_for needs the option :wrapper => 'inline' which can be handed down as follows:

= link_to_add_association 'add something', f, :something, :render_options => {:wrapper => 'inline' }

Callbacks (upon insert and remove of items)

There is an option to add a callback on insertion or removal. If in your view you have the following snippet to select an owner (we use slim for demonstration purposes)

#owner
  #owner_from_list
    = f.association :owner, :collection => Person.all(:order => 'name'), :prompt => 'Choose an existing owner'
  = link_to_add_association 'add a new person as owner', f, :owner

This view part will either let you select an owner from the list of persons, or show the fields to add a new person as owner.

The callbacks can be added as follows:

$(document).ready(function() {
    $('#owner').bind('insertion-callback',
         function() {
           $("#owner_from_list").hide();
           $("#owner a.add_fields").hide();
         });
    $('#owner').bind("removal-callback",
         function() {
           $("#owner_from_list").show();
           $("#owner a.add_fields").show();
         });
});

Do note that for the callbacks to work there has to be a surrounding container (div), where you can bind the callbacks to.

Control the Insertion behaviour

The default insertion location is at the back of the current container. But we have added two data-attributes that are read to determine the insertion-node and -method.

For example:

$(document).ready(function() {
    $("#owner a.add_fields").
      data("association-insertion-method", 'before').
      data("association-insertion-node", 'this');
});

The association-insertion-node will determine where to add it. You can choose any selector here, or specify this (default it is the parent-container).

The association-insertion-method will determine where to add it in relation with the node. Any jQuery DOM Manipulation method can be set but we recommend sticking to any of the following: before, after, append, prepend. It is unknown at this time what others would do.

Partial

The partial should be named _<association-object_singular>_fields, and should start with a container (e.g. div) of class .nested-fields.

There is no limit to the amount of nesting, though.

Note on Patches/Pull Requests

  • Fork the project.
  • Make your feature addition or bug fix.
  • Add tests for it. This is important so I don't break it in a future version unintentionally.
  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
  • Send me a pull request. Bonus points for topic branches.

Todo

  • add more sample relations: has_many :through, belongs_to, ...
  • improve the tests (test the javascript too)(if anybody wants to lend a hand ...?)

Copyright

Copyright (c) 2010 Nathan Van der Auwera. See LICENSE for details.

Source : https://github.com/nathanvda/cocoon

 

 

Three Ways of Installing Ruby

You can get a copy of Ruby in a variety of ways, and different people prefer each of the three methods for different reasons. Each will have a section below, but here’s an overview:

  • Compiling from Source is the standard way that software has been delivered for many, many years. This will be most familiar to the largest number of software developers.
  • There are a few third party tools to install Ruby. These are often simpler for total newbies or the most advanced of users.
  • Finally, A few package management systems support Ruby. This will be most familiar to people who use one operating system for everything, and like to stick to those individual standards.

Finally, if you want to run multiple versions of Ruby on the same machine, check the third party tools section and use rvm. It’s by far the best way to accomplish that, unless you know exactly what you’re doing.

Compiling Ruby — Source code

Installing from the source code is a great solution for when you are comfortable enough with your platform and perhaps need specific settings for your environment. It’s also a good solution in the event that there are no other premade packages for your platform.

If you have an issue compiling Ruby, consider using one of the third party tools in the next section. They may help you.

  • Ruby 1.9.3-p0 (md5: 8e2fef56185cfbaf29d0c8329fc77c05) Stable (recommended)
  • Stable Snapshot This is a tarball of the latest snapshot of the Stable branch.
  • Nightly Snapshot This is a tarball of whatever is in svn, made nightly. This may contain bugs or other issues, use at your own risk!

For information about the Ruby Subversion and Git repositories, see our Ruby Core page.

Third Party Tools

Many Rubyists use third-party tools to help them install Ruby. They confer various advantages, but are not officially supported. Their respective communities are very helpful, however.

RVM

The most popular tool to install Ruby is RVM, for “Ruby Version Manager.” Not only does it make installing Ruby incredibly easy, it also allows you to install and manage multiple copies of Ruby on your system, as well as multiple alternate implementations of Ruby.

RVM is only available for Mac OS X, Linux, or any UNIX-like operating system. Windows users should check out pik for a similar project, or consider using RubyInstaller, described in the next section.

As of this writing, as long as you have git installed, you can install RVM with:

$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

For the latest instructions on installing rvm, check out the RVM installation page. Installing the latest Ruby version with RVM is simply done by typing rvm install 1.9.3. RVM can also install most of the Ruby implementations listed below. To see all supported versions, type rvm list known.

RubyInstaller

If you’re on Windows, there’s a great project to help you install Ruby:RubyInstaller. It gives you everything you need to set up a full Ruby development environment on Windows.

To use RubyInstaller, download it from the RubyInstaller download page. Then just use the installer, and you’re done!

If you are installing Ruby in order to use Rails, you should use RailsInstallerwhich uses RubyInstaller but gives you extra tools that help with Rails development.

Package Management Systems

If you can’t compile your own Ruby, and you don’t want to use a third party tool, you can use your system’s package manager to install Ruby.

Certain members of the Ruby community feel very strongly that you should never use a package manager to install Ruby, and that you should use RVMinstead. While the full list of pros and cons are outside of the scope of this page, the most basic reason is that most package managers have older versions of Ruby in their repositories. If you’d like to use the newest Ruby, make sure you use the correct package name, or use RVM instead.

Linux

Debian GNU/Linux uses the apt package manager system. (So does Ubuntu.) You can use it like this:

$ sudo apt-get install ruby1.9.1

Yes, this will install Ruby 1.9.2. It has a ‘library compatibility version’ of 1.9.1, hence the name.

If you install the ‘ruby’ package, you’ll get the older Ruby 1.8.

Arch Linux uses a package manager named pacman. To get Ruby, just do this:

$ sudo pacman -S ruby

On other systems, RVM might be the right choice for you, or you can search the package repository for your Linux distro’s manager.

Mac OS X

Ruby 1.8.7 is fully supported in Mac OS X Lion as well as many popular Ruby gems (packages). For details, see the Ruby wiki at MacOS Forge.

Mac OS X Tiger is packaged with version 1.8.2 of Ruby, and Leopard ships with 1.8.6, but, for those who haven’t upgraded to Leopard, there are a number of options for installing the latest version of Ruby.

Many people on Mac OS X use Homebrew as a package manager. It’s really easy to get Ruby:

$ brew install ruby

Also, since OS X is based on Unix, downloading and installing from the source is just as easy and effective as the other solutions. To help you with installation of new Ruby versions on OS X, it’s probably a good idea to use RVM. Type rvm notes for system-specific information.

For a detailed look at installing Ruby (and Rails), Dan Benjamin’s excellent articles for Tiger, for Leopard, and for Snow Leopard will get you up and running very quickly. On Lion, this article can help you.

Ruby On Solaris and OpenIndiana

Ruby 1.8.7 are available for Solaris 8 through Solaris 10 on Sunfreeware and Ruby 1.8.7 is available at Blastwave. Ruby 1.9.2p0 is also available atSunfreeware, but this is outdated. Using RVM can get you the latest version of Ruby 1.9.2.

To install Ruby on OpenIndiana, please use the Image Packaging System, orIPS client. This will install the latest Ruby binaries and Rubygems directly from the OpenSolaris network repository for Ruby 1.9. It’s easy:

% pkg install runtime/ruby-18

Like before, RVM is a good way to obtain Ruby 1.9.2, the latest version.

Other Implementations of Ruby

Ruby, as a language, has a few different implementations. This guide has been discussing the reference implementation, MRI, but there are also others. They are often useful in certain situations, provide extra integration to other languages or environments, or have special features that MRI doesn’t.

Here’s a list:

  • JRuby is Ruby atop the JVM (Java Virtual Machine), utilizing the JVM’s optimizing JIT compilers, garbage collectors, concurrent threads, tool ecosystem, and vast collection of libraries.
  • Rubinius is ‘Ruby written in Ruby.’ Built on top of LLVM, Rubinius sports a nifty virtual machine that other languages are being built on top of, too.
  • MacRuby is a Ruby that’s tightly integrated with Apple’s Cocoa libraries for Mac OS X, allowing you to write desktop applications with ease.
  • Cardinal is a “Ruby compiler for Parrot Virtual Machine” (Perl 6).
  • IronRuby is an implementation “tightly integrated with the .NET Framework”.
  • MagLev is “a fast, stable, Ruby implementation with integrated object persistence and distributed shared cache”.

Some of those implementations, including MRI, follow the guidelines ofRubySpec, a “complete executable specification for the Ruby programming language”.

Source : http://www.ruby-lang.org/en/downloads/

Properties and Methods in Ruby from a .NET POV

C# developers are used to working with fields, properties, and methods. But there’s certain confusion when it comes to understanding how those work in Ruby. So let’s have a quick C# refresher.

Fields, Properties, and Methods in C#

Fields are variables scoped either to an object (instance fields) or to a class (static fields). As a best practice, developers don’t expose fields publicly, as doing so exposes too much of the internals of a class. An instance field is declared like so:

1 public class Customer
2 {
3   private int _age;
4 }

Notice that the underscore before “age” is just a common convention that several C# developers follow. In order to expose such a field, one creates a “property”, which is defined as a pair of a getter and a setter method:

1 public class Customer
2 {
3   private int _age;
4   public int Age
5   {
6     get { return _age; }
7     set { _age = value; }
8   }
9 }

A property is defined only with a get method in case it’s only meant to be “accessed”, but not “assigned”. In cases where getters and setters simply get or set the value of a field, one may use a feature of C# called auto properties:

1 public class Customer
2 {
3   public int Age { get; set; }
4 }

When a property is defined like that, the C# compiler produces code similar to the one I had shown before (it creates the backing field, and the implementation of getters/setters).

Now, What Does That Look Like in Ruby…?

The following post briefly covered instance and class variables: NET to Ruby: Methods and Variables. In order to declare an instance variable, we define it in a class’ initializer (its constructor), preceeding it with an @:

1 class Customer
2   def initialize
3     @age = 18
4   end
5 end

At this point, @age is very similar to a private field in C#, in that it can be accessed anywhere within the class where it is defined, but not outside of it. In order to access or assign it from the outside, we must define accessor methods to it:

01 class Customer
02   def initialize
03     @age = 18
04   end
05   def age
06     @age
07   end
08   def age=(value)
09     @age = value
10   end
11 end

Different than in C#, where we defined an Age property containing set and get methods, here we created an age method that returns the value of the @age instance variable, and also an age= method, which takes in a value and assigns it to the instance variable.

Similarly to C#’s auto properties, Ruby also offers a construct that allow for easy creation of accessors. The code above could be rewritten like so:

1 class Customer
2   def initialize
3     @age = 18
4   end
5   attr_accessor :age
6 end

attr_accessor is not a keyword in Ruby; it is something called a “class macro”, which is a meta programming technique to add dynamic behavior to a class. In this case, what gets added are the reader and writer accessors. We can also only add either the reader or write accessors by using attr_reader or attr_writer, respectively.

Accessors That Do a Little More…

It’s very common to create a property in C# where the accessors may do a little more than just get and/or set the value of an instance variable. For example, maybe the getter needs to concatanate values before returning it:

1 public class Customer
2 {
3   private string _firstName;
4   private string _lastName;
5   public string FullName
6   {
7     get { return string.Format("{0} {1}", _firstName, _lastName); }
8   }
9 }

In the example above, the FullName property has a getter that concatenates the _firstName and _lastName fields. Such practice is common in Ruby as well:

1 class Customer
2   def initialize
3     @first_name = "Claudio"
4     @last_name = "Lassala"
5   end
6   def full_name
7     "#{@first_name} #{@last_name}"
8   end
9 end

Keep in mind that parenthesis are optional in Ruby, so a method such as full_name above can be called like so:

1 cust = Customer.new
2 puts cust.first_name

Cleaning Up the Code With Metaprogramming

Quite often we add boolean properties to a class so we can ask an object about certain things. Take this example:

01 public class User
02 {
03   private string _profile;
04   public User(string profile)
05   {
06     _profile = profile;
07   }
08   public bool IsDoctor
09   {
10     get { return _profile == "doctor"; }
11   }
12   public bool IsPatient
13   {
14     get { return _profile == "patient"; }
15   }
16 }

Now assume that there are more types of profiles then just “doctor” and “patient”, so the User class would end up having one property for each type of profile in this case. Similar class could be created in Ruby like so:

01 class User
02   def initialize(profile)
03     @profile = profile
04   end
05   def doctor?
06     @profile == 'doctor'
07   end
08   def patient?
09     @profile == 'patient'
10   end
11 end

What’s with the “?” suffix for the doctor? and patient? methods? Often, when a method in Ruby is meant to return a boolean, the method is called a predicate method, and it is common practice to have it with a “?” suffix. So instead of writing code such as “if user.is_doctor”, we write “if user.doctor?”.

If there’s really potential for the User class to have several methods such as doctor? and patient? (one for each type of profile), the class could be rewritten to leverage some metaprogramming. Here’s an example of what that could look like:

01 class User
02   def initialize(profile)
03     @profile = profile
04   end
05   def method_missing(method_name, *args, &block)
06     method_name = method_name.to_s
07     if method_name.ends_with?("?")
08       return @profile == method_name.chop
09     end
10     super if self.responds_to?(method_name)
11   end
12 end

Notice that both the doctor? and patient? methods are gone, and a method_missing method has been added. What happens now is that whenever some code queries the user object like “if user.doctor?”, such method is missing in the class, and the method_missing method gets called. In the example above, the method_missing checks whether the method being called on the object (“method_name”) ends with a “?”, and if it does, it compares @profile to it. If new profiles are supported, there is no need to add properties to the User class, as it is ready to handle it.

Summary

It’s important to understand the fact that there aren’t really “properties” in Ruby (there are methods, instead), and those can either be created automatically (using attr_accessor, attr_reader, attr_writer class macros) or manually (by simply defining the methods), since these things are used quite a bit in every application.

I hope you now have a better grip on how C# and Ruby compare when it comes to properties.