Created
November 12, 2015 11:05
-
-
Save deepakdargade/2b06d85770f2093a7153 to your computer and use it in GitHub Desktop.
10 Ruby Tricks to Make Your Code Nearly Perfect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#http://www.queness.com/post/17464/10-ruby-tricks-to-make-your-code-nearly-perfect | |
Ruby is awesome! If you think it’s not, you just haven’t got an opportunity to explore the simplicity, elegance and power of Ruby. | |
A lot of web services and enterprise level platforms use Ruby. Which ones? Twitter, Shopify, Crunchbase, Groupon. What about software? Top orchestrators - Puppet and Chef - are written in Ruby. Millions of user and thousands of developers love this language. And to love it even more, let’s go through some tips and tricks that will make your Ruby code beautiful. Here are tricks provided by Ruby on Rails develompent company RW. | |
1. Organize your list of values into a hash | |
Say, you have a list of values, and to make it easy to process them, why not create a hash? The syntax is pretty straightforward - Hash[...]. Here’s a short example: | |
Hash['key1', 'value1', 'key2', 'value2'] | |
# => {"key1"=>"value1", "key2"=>"value2"} | |
2. Lambda Literal -> | |
Lambda expressions is the new big thing in Java 8. Ruby’s not lagging behind. Lambdas are an excellent way to define scopes in Ruby and if you did not know that you do now! Welcome, Lambda Literal -> | |
a = -> { 1 + 1 } | |
a.call | |
# => 2 | |
a = -> (v) { v + 1 } | |
a.call(2) | |
# => 3 | |
3. What Double stars (**) can do | |
The double star is a neat little trick in Ruby. See the following method: | |
OK, let’s take a look at the below method. It features a double star: | |
def my_method(a, *b, **c) | |
return a, b, c | |
end | |
Who is who here? It’s clear enough that ‘a’ is just an ordinary parameter. Nothing fancy here. *b is commanded to take all parameters after the first one. These parameters will be saved in an array. **c accepts all parameters passed after the method call (at the end of it). | |
Here are some examples to illustrate it: | |
One parameter | |
new_method(1) | |
# => [1, [], {}] | |
1+ parameters | |
new_method(1, 2, 3, 4) | |
# => [1, [2, 3, 4], {}] | |
Several parameters and hash-style parameters | |
new_method(1, 2, 3, 4, a: 1, b: 2) | |
# => [1, [2, 3, 4], {:a=>1, :b=>2}] | |
As you can see, you can easily organize data in a way that makes it easy to process and re-use in your code. | |
4. Arrays and objects should be handled exactly the same way | |
Sometimes you might want to give the option to either accept a single object or an array of objects. Instead of checking for the type of object you’ve received, you could use [*something] or Array(something). | |
In your code you may choose if or not you want to accept an array. Sometimes, you should only process a single object. Of course, you may check what kind of object you have received. But that’s an extra line of code and additional logic. | |
Here are two examples of working with arrays and single objects. First off, let’s define variables. | |
variable = 1 | |
variable _arr = [1, 2, 3] | |
Now, let’s loop through using [*...]: | |
[*variable ].each { |s| s } | |
[*variable _arr].each { |s| s } | |
It’s time to work with an array - Array(...). | |
Array(variable ).each { |s| s } | |
Array(variable _arr).each { |s| s } | |
5. Double Pipe Equals ||= | |
The Double Pipe Equals is a great tool to write concise code. Double pipe equal is a cool thing! Some examples never hurt: | |
a || a = b # Correct | |
However, some folks will think of this one: | |
a = a || b # Wrong | |
Why is it wrong? Well, why reassign variable a? We have it already! | |
Now, let’s perform some calculations: | |
def total_sum | |
@total ||= (2..10000000).to_a.inject(:+) | |
end | |
Now you could have other method calling total to get the total value but it will only be calculated the first time. | |
This method will perform calculation only having been called the first time! How cool is that, huh? | |
6. Ask for parameters to be accepted: Mandatory hash parameters | |
This is a Ruby 2.0 feature. The traditional way to define a method that take a hash of parameters is the following: | |
def new_method({}) | |
end | |
You can specify the keys that you are waiting for and even define default values for them! a and b are mandatory keys. | |
However, you may go further and specify what keys and default values such a method expects: | |
def new_method(a:, b:, c: 'value1') | |
return a, b, c | |
end | |
Let’s call this method with various parameters passed over: | |
new_method(a: 2) | |
# => ArgumentError: missing keyword: b | |
Why didn’t the interpreter complain over missing c? It’s because it already has a predefined value in the method declaration. Here’s an example: | |
new_method(a: 2, b: 3) | |
# => [2, 3, "value1"] | |
And now let’s pass all 3 values: | |
new_method(a: 1, b: 2, c: 3) | |
# => [1, 2, 3] | |
There’s a more elegant way to pass parameters, for instance saving them to a hash and then passing this hash to the method: | |
hash = { a: 1, b: 2, c: 3 } | |
new_method(hash) | |
# => [1, 2, 3] | |
7. How to easily generate numbers or alphabet | |
You might want to generate a list of numbers or put the entire alphabet inside an array. Well, you can use ruby ranges to do this. | |
For some reason, you may need to generate an alphabet or just a pre-defined list of numbers. Defining a range in Ruby is a piece of cake. | |
English alphabet: | |
('a'..'z').to_a | |
# => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] | |
Number from 1 to 11 | |
(1..11).to_a | |
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] | |
8. Improving your code with taps | |
A tap can make your code more readable. Let’s create a simple class: | |
class User | |
attr_accessor :a, :b, :c | |
end | |
Now, let’s define a method that creates a new user with a sect of attributes. Here’s a traditional way: | |
def new_method | |
o = User.new | |
o.a = 1 | |
o.b = 2 | |
o.c = 3 | |
o | |
end | |
Or you could use tap to do it like this. | |
def new_method | |
User.new.tap do |o| | |
o.a = 1 | |
o.b = 2 | |
o.c = 3 | |
end | |
end | |
The object being called is saved to a block and is then returned. | |
9. Default value for hash | |
If some value is not defined in a hash and you attempt to access it, you’ll get nil. However, this behavior can be changed. Make sure you do it with caution! | |
Here’s an example of defining the default value to be 0, so we get 0 back but not nil. | |
a = Hash.new(0) | |
a[:a] | |
# => 0 | |
Easy! You can define anything here. An empty hash? No problems! | |
a = Hash.new({}) | |
a[:a] | |
# => {} | |
Maybe a random string? OK, let’s do it: | |
a = Hash.new('rubyrules’’) | |
a[:a] | |
# => rubyrules" | |
10. heredocs: how to make your code prettier | |
EOT is sensitive to leading spaces. So, your code will look like this: | |
Textpop-Up | |
def my_method | |
<<-EOT | |
Hello | |
World | |
EOT | |
end | |
That works, but there’s a way to better format this chunk of code. Let’s use gsub method with a simple regex that will remove leading spaces. Automation rules: | |
Textpop-Up | |
def my_method | |
<<-EOT.gsub(/^\s+/, '') | |
Hello | |
World | |
EOT | |
end | |
Sure, this is just a small token of knowledge that you can get on Ruby. But hopefully, it should be a good start! | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment