23
Ruby on Rails tips 2013.04.29 hebinbin.herokuapp.com

Ruby on rails tips

Embed Size (px)

DESCRIPTION

some tips for ruby on rails

Citation preview

Page 1: Ruby  on rails tips

Ruby on Rails tips2013.04.29

hebinbin.herokuapp.com

Page 2: Ruby  on rails tips

Object::try - 1Sometimes you write down the code like: user ? user.name : ‘No name’ We can use try function to optimize code user.try(:name) || ‘No name’

-> if user is not nil, display user.name -> if user is nil, nil.try(:name) will be nil nil || ‘No name’ will be ‘No name’

Page 4: Ruby  on rails tips

Object::presence1) nil.presence #=> nil2) [].presence #=> nil3) {}.presence #=> nil4) “” .presence #=> nil5) ‘’ .presence #=> nil

6) false.presence #=> nilSo you can change code like

params[:name].present? ? params[:name] : ‘No name’

Toparams[:name].presence || ‘No name’

Page 5: Ruby  on rails tips

Object::send -1class Hoge def test; puts ‘test’; endend

Hoge.new.test #=> ‘test’Hoge.new.send(:test) #=> ‘test’Hoge.new.send(‘test’) #=> ‘test’Hoge.new.send(‘testother’) #=> NoMethodError

So object uses send to read method

Page 6: Ruby  on rails tips

Object::send -2Why we need to use send method:1. By using send method, we can read private

method. If you want to test private method, you can use send method

class Hoge def private_test; puts ‘private’; end private :private_test end Hoge.new.private_test #=> NoMethodError Hoge.new.send(:private_test) #=> ‘private’

Page 7: Ruby  on rails tips

Object::send -3Why we need to use send method:2. We can pass method name as method parameter: class Hoge def send_test(method_name) self.send(method_name) end def other_method ‘test’ end endHoge.new.send_test(:other_method) #=> ‘test’

Page 8: Ruby  on rails tips

freezeWhen you do not want to change some constants or instance variables in the program, you can use freeze.

DAYS=[‘Mon’, ‘Tues’, ‘Wes’] DAYS << ‘Sat’ puts DAYS #=> =[‘Mon’, ‘Tues’, ‘Wes’, ‘Sat’] DAYS=[‘Mon’, ‘Tues’, ‘Wes’].freeze DAYS << ‘Sat’ #=> can't modify frozen Array (RuntimeError)

Page 9: Ruby  on rails tips

inject -1If you are familiar with C or Java, when you want to get sum from 1 to 10, maybe you will write ruby code like: sum = 0 (1..10).each { |i| sum = sum + I } puts sum #=> 55

In ruby, you can use the other ways: puts (1..10).inject(0) { |sum, i| sum + I }

Page 10: Ruby  on rails tips

inject -2You can also use inject like:

my_hash = { a: 'foo', b: 'bar' } # => {:a=>"foo", :b=>"bar"}

a_new_hash = my_hash.inject({}) { |h, (k, v)| h[k.upcase] = v.upcase; h } # => {:A=>"FOO", :B=>"BAR"}

Page 11: Ruby  on rails tips

tap -1When you want to change object itself and return this object, you can use tap method.

The source code look like:class Object def tap yield(self) self end end

Page 12: Ruby  on rails tips

tap -2ary = [3, 7, 6, 12]{}.tap {|h| ary.each{|x| h[x] = x**2} } # => {3=>9, 7=>49, 6=>36, 12=>144}{} changes itself to {3=>9, 7=>49, 6=>36, 12=>144}

Page 13: Ruby  on rails tips

tryrubyIf you do not want to install ruby on your pc,You can use online ruby:

http://tryruby.org/levels/1/challenges/0

Page 14: Ruby  on rails tips

define numberIn ruby, if the number is too bigger to make mistake easily, you can write code like:Irb > 100_000# => 100000Irb >  

Page 15: Ruby  on rails tips

HashWithIndifferentAccess

In some cases, you will find that:

x = {"key1" => "value1"}x["key1"] #=> "value1" x[:key1] #=> nil

How can you use both x["key1"] and x[:key1] to get same result ?

x = {"key1" => "val1"} x = x.with_indifferent_access x[:key1] #=> "val1“ x["key1"] #=> "val1"

Page 16: Ruby  on rails tips

assert_valid_keysSometimes, you will see some codes like:Image_tag(sym, options={})

When you get options, nomrally we should check the keys are existed or not. So you can use assert_valid_keys

def do_something(options = {}) options.assert_valid_keys :x, :y # do the real something end

If the options contains any other keys, an ArgumentError will be raised.

PS: the better way should be delete other keys.

Page 17: Ruby  on rails tips

Extend ruby class -1Back to example which we given before, you want to create a new method for hash to get_valid_keys: class Hash def get_valid_keys(*args) end end

So in ruby on rails, how to extend it ?

Page 18: Ruby  on rails tips

Extend ruby class -21. Put the code into lib/core_ext/hash.rbYou also need the following code in your initializer config:

Dir[File.join(Rails.root, "lib", "core_ext", "*.rb")].each {|l| require l }

At last, restart your app.

2. Put the code into config/initializers/hash.rbThen restart your app.

Page 19: Ruby  on rails tips

Set union• Join two arrays and remove duplicates with pipe

operator (|)

[ "a", "b", "c" ] | [ "c", "d", "a" ] # => ["a", "b", "c", "d"]

Page 20: Ruby  on rails tips

RubyInlineWhen you want to run C or C++ language in your ruby code to improve performance , plz check following website.

https://github.com/seattlerb/rubyinline

Page 21: Ruby  on rails tips

Use chainIn ruby, we can use chain to avoid using temp variables for example: #bad code hoge = Hoge.new puts hoge.name #good code puts Hoge.new.name

Page 22: Ruby  on rails tips

performance1. Ruby is an interpreted language and

interpreted languages will tend to be slower than compiled ones

2. Ruby uses garbage collection3. Ruby (with the exception of JRuby) does not

support true multithreading.4. Ruby is heavy memory.5. Instantiating too many active record objects is a

place where rails app's memory footprint really grows. (Flyweight Pattern: http://en.wikipedia.org/wiki/Flyweight_pattern#Example_in_Ruby)

Page 23: Ruby  on rails tips

Why ruby does not support ture multi-threading?

• In Ruby you have got Global Interpreter Lock, so only one Thread can work at a time. So, Ruby spend many time to manage which Thread should be fired at a moment (thread scheduling). So in your case, when there is no any IO it will be slower!

• You can use Rubinius or JRuby to use real Threads.

• Jruby implements threads with JVM threads, which in turn uses real threads.