https://tduyng.com/atom.xml

Better In Ruby - 01

2020-08-01

Some tips you probably don't know in Ruby.

Today, I will make a series that I learned about tips and tricks in ruby.

Assigning the rest of an array to a variable

When destructuring an array, you can unpack and assign the remaining part of it to a variable using the rest pattern

  a = [1, 2, 3]
  b, *rest = *a

  b    # => 1
  rest # => [2, 3]
  a    # => [1, 2, 3]

Word array

When we want to add a separator in the string

%w{This is a string, I want to separate by a comma} * ", "
# "This, is, a, string,, I, want, to, separate, by, a, comma"

Concate array

[1, 2, 3] * 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3] # true
new_array = Array.new([0], 5) # [0,0,0,0,0]

Format decimal

number = 9.5
"%.2f" % number # => "9.50"
number.round(2)

Remove a folder

This is a relatively common job of developer. There a many different ways to delete a folder and this is one of the shortest and fastest way to do:

require 'fileutils'
FileUtils.rm_r 'somedir'

Massive assignment

Massive assignment allow us to declare many variables at the same time

a,b,c,d = 1,2,3,4

This feature will be very useful in the method with many parameters

def my_method(*args)
  a,b,c,d = args
end

Deep copy

When we copy an object that contains others objects inside, array for example, you only copy references to those objects

food = %w( bread milk orange )
food.map(&:object_id)
=> [69612840, 69612820, 69612800]
[122] pry(main)> food.clone.map(&:object_id)
=> [69612840, 69612820, 69612800]

Using Marshal (usually use for serialization), you can create a deep copy.

def deep_copy(obj)
  Marshal.load(Marshal.dump(obj))
end

See the result:

ObjectSpace.each_object(String).select{|x| x == food.first}.count
=> 54
deep_copy(food).map &:object_id
=> [77564660, 77564420, 77564300]
ObjectSpace.each_object(String).select{|x| x == food.first}.count
=> 56

Bonus: Difference between clone and dup(They are almost the same, but there are two points that dup doesn't have)

  • Clone also singleton class of copied object
  • Keep the frozen state of copied object

For example:

  • Singleton methods

    a = Object.new
    def a.foo; :foo end
    p a.foo
    => :foo
    b = a.dup
    p b.foo
    => undefined method `foo' for #<Object:0x007f8bc395ff00> (NoMethodError)
    c = a.clone
    c.foo
    => :foo
    
  • Frozen state

    a = Object.new
    a.freeze
    p a.frozen?
    => true
    b = a.dup
    p b.frozen?
    => false
    c = a.clone
    p c.frozen?
    => true
    

Create a an array with random values

Array.new(10) { rand 300 }

It will create an array with 10 item that have the random values from 0 to 299


Thanks you for reading! Stay tunned to update the next chapter.