Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between Kernel#yield_self, yield(self) and Object#tap in ruby

Ruby 2.5.0-rc1 has been released and introduces a new Kernel#yield_self method.

What is the difference between yield_self, yield(self) and the existing Object#tap method?

like image 530
Vivek Singh Avatar asked Dec 19 '17 15:12

Vivek Singh


People also ask

What are the different type of kernel?

Kernel is the main and central component of an OS. It has five types, namely, monolithic kernel, microkernel, hybrid kernel, nano kernel, and exo kernel. The functions of a kernel include accessing computer resources, memory management, device management, and resource management.

What is the difference between Linux kernel and OS?

The Linux® kernel is the main component of a Linux operating system (OS) and is the core interface between a computer's hardware and its processes. It communicates between the 2, managing resources as efficiently as possible.

What is the main function of kernel?

The kernel performs its tasks, such as running processes, managing hardware devices such as the hard disk, and handling interrupts, in this protected kernel space. In contrast, application programs such as browsers, word processors, or audio or video players use a separate area of memory, user space.

What is the relationship of kernel and operating system?

Kernel is basically a bridge between software and hardware of the system. The basic difference that distinguishes kernel and operating system is that operating system is the package of data and software that manages the resources of the system, and the kernel is the important program in the operating system.


1 Answers

The difference between tap and yield_self is in what is returned by each of the two methods.

Object#tap yields self to the block and then returns self. Kernel#yield_self yields self to the block and then returns the result of the block.

Here are some examples of where each can be useful:

tap

Replacing the need for a result line at the end of a method:

def my_method   result = get_some_result   call_some_method_with result   result end 

can be written as:

def my_method   get_some_result.tap do |result|     call_some_method_with result   end end 

Another example is initialisation of some object that takes several steps:

some_object = SomeClass.new.tap do |obj|   obj.field1 = some_value   obj.field2 = other_value end    

yield_self and yield(self)

If used inside one of your own methods yield_self would have the same effect as yield(self). However, by having it as a method in its own right this promotes method chaining as an alternative to nested function calls.

This blog post by Michał Łomnicki has some helpful examples. e.g. this code:

CSV.parse(File.read(File.expand_path("data.csv"), __dir__))    .map { |row| row[1].to_i }    .sum 

can be rewritten as:

"data.csv"   .yield_self { |name| File.expand_path(name, __dir__) }   .yield_self { |path| File.read(path) }   .yield_self { |body| CSV.parse(body) }   .map        { |row|  row[1].to_i }   .sum 

This can aid with clarity where nested calls are being used for a series of transformations on some data. Similar features exist in other programming languages. The pipe operator in Elixir is a good one to take a look at,

like image 177
mikej Avatar answered Sep 19 '22 10:09

mikej