Better In Ruby - 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.