Skip to content

Instantly share code, notes, and snippets.

@hadrienblanc
Last active December 19, 2018 09:06
Show Gist options
  • Save hadrienblanc/aeb5c3f13394ad9f42b1ea40ab0fe6e2 to your computer and use it in GitHub Desktop.
Save hadrienblanc/aeb5c3f13394ad9f42b1ea40ab0fe6e2 to your computer and use it in GitHub Desktop.
Overlooked methods of the ruby object

Ruby object

Overlooked methods of the ruby object.

yield_self {|x| block } → an_object

(ruby 2.5) Yields self to the block and returns the result of the block.

"my string".yield_self {|s| s.upcase }   #=> "MY STRING"
3.next.yield_self {|x| x**x }.to_s       #=> "256"

tap{|x|...} → obj

enum_for(method = :each, *args) → enum

enum_for(method = :each, *args){|*args| block} → enum Creates a new Enumerator which will enumerate by calling method on obj, passing args if any.

str = "xyz"

enum = str.enum_for(:each_byte)
enum.each { |b| puts b }
# => 120
# => 121
# => 122

# protect an array from being modified by some_method
a = [1, 2, 3]
some_method(a.to_enum)

frozen? → true or false

Returns the freeze status of obj.

a = [ "a", "b", "c" ]
a.freeze    #=> ["a", "b", "c"]
a.frozen?   #=> true

on dup vs clone

In general, clone and dup may have different semantics in descendant classes. While clone is used to duplicate an object, including its internal state, dup typically uses the class of the descendant object to create the new instance.

When using dup, any modules that the object has been extended with will not be copied.

class Klass
  attr_accessor :str
end

module Foo
  def foo; 'foo'; end
end

s1 = Klass.new #=> #<Klass:0x401b3a38>
s1.extend(Foo) #=> #<Klass:0x401b3a38>
s1.foo #=> "foo"

s2 = s1.clone #=> #<Klass:0x401b3a38>
s2.foo #=> "foo"

s3 = s1.dup #=> #<Klass:0x401b3a38>
s3.foo #=> NoMethodError: undefined method `foo' for #<Klass:0x401b3a38>

dig

address = params[:account].try(:[], :owner).try(:[], :address)

# or

address = params[:account].fetch(:owner) .fetch(:address)

You can now simply use Hash#dig and accomplish the same thing:

address = params.dig(:account, :owner, :address)

The Safe Navigation Operator (&.) in Ruby

account = Account.new(owner: nil) # account without an owner

account.owner.address
# => NoMethodError: undefined method `address' for nil:NilClass

account && account.owner && account.owner.address
# => nil

account.try(:owner).try(:address)
# => nil

account&.owner&.address
# => nil

Should know, but still overlooked

class

Classname of the object

object_id → integer

Returns an integer identifier for obj.

respond_to?(symbol, include_all=false) → true or false

Returns true if obj responds to the given method.

send

class Klass
  def hello(*args)
    "Hello " + args.join(' ')
  end
end
k = Klass.new
k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"

block & methods

def my_method
  puts "reached the top"
  yield
  puts "reached the bottom"
end

my_method do
  puts "reached yield"
end

# output
reached the top
reached yield
reached the bottom
def my_method
  yield("John", 2)
  puts "Hi #{name}"
end

my_method { |name, age| puts "#{name} is #{age} years old" }

# output
John is 2 years old
NameError: undefined local variable or method `name' for #<IRB::...>

more on blocs : https://mixandgo.com/learn/mastering-ruby-blocks-in-less-than-5-minutes

to dig 🔧 :

@hadrienblanc
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment