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?
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.
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.
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.
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.
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:
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
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,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With