In Ruby, What Are the Vertical Lines

In Ruby, what are the vertical lines?

It's for the parameters that are being passed to your block. i.e. in your example, upto will call your block with each number from 1 to 9 and the current value is available as x.

The block parameters can have any name, just like method parameters. e.g. 1.upto(9) { |num| puts num } is valid.

Just like parameters to a method you can also have multiple parameters to a block. e.g.

hash.each_pair { |key, value| puts "#{key} is #{value}" }

What does two vertical lines and super.select mean in a code block?

That is kind of weird piece of code, but this is what its doing:

you are defining a method called method

the special method super means to call the same named method on the parent (super) class.

the you are taking the result of super, which must be an "enumerable" object, such as an Array or a hash and calling select on that object

select goes through the enumerable object (lets assume its an array) and calls the block with each element. Typically its used to filter (or select) some objects from the array. Each time the block is called it returns a truthy or falsy value. If truthy then that element is kept in the resulting array. If falsy its thrown out.

Okay so every element of this array is going to have this executed on it:

a.meets_condition? || true

which is bizarre because what this is going to do is call meets_condition? on the element of the array, and if it returns a truthy value then that element (a) is kept in the array.

but what if a.meets_condition? is falsy?

Then we go on to the next part of the or (the double pipes) and do that.

Which returns true.

So basically this expression is going to return a copy of the array you passed in.

Lets make the example into an actual working example:

class RandomDigit
# gives you a object containing a random digit between 0 and 9
def initialize
@n = rand(10)
end
def meets_condition? # returns true if @n is even
@n % 2 == 0
end
end

class TheParentClass
def method
# returns array of 4 random digits (between 0 and 9)
[RandomDigit.new, RandomDigit.new, RandomDigit.new, RandomDigit.new]
end
end

class TheChildClass < TheParentClass
def method
# super means we are calling TheParentClass.method
# select will try each element of the the array
# and builds a new array, with elements that returned true
# but the trouble is || true means its always going to return true
super.select { |a| a.meets_condition? || true }
end
end

puts TheChildClass.new.method # -> returns 4 random digits

You can click on this link to run the code and see it work

http://opalrb.com/try/?code:class%20RandomDigit%0A%20%20def%20initialize%0A%20%20%20%20%40n%20%3D%20rand(10)%0A%20%20end%0A%20%20def%20meets_condition%3F%0A%20%20%20%20%40n%20%25%202%20%3D%3D%200%20%23%20returns%20true%20if%20%40n%20is%20even%0A%20%20end%0Aend%0A%0Aclass%20TheParentClass%0A%20%20def%20method%0A%20%20%20%20%23%20returns%204%20random%20digits%20(between%200%20and%209)%0A%20%20%20%20%5BRandomDigit.new%2C%20RandomDigit.new%2C%20RandomDigit.new%2C%20RandomDigit.new%5D%0A%20%20end%0Aend%0A%0Aclass%20TheChildClass%20%3C%20TheParentClass%0A%20%20def%20method%0A%20%20%20%20super.select%20%7B%20%7Ca%7C%20a.meets_condition%3F%20%7C%7C%20true%20%7D%0A%20%20end%0Aend%0A%0Aputs%20TheChildClass.new.method

Just to be clear the only thing that doesn't really make sense here is the || true part.

Otherwise this would be that you are defining a new class, and you are slightly changing the behavior of method so that it works sort of like the original method but filters out the elements.

Usually you might see something like a.question_1? || a.question_2?

which would be try question_1? and if it returns true then we are done.

if it doesn't return true, then try question_2.

This is because || is a flow of control operation... the second part does NOT get executed if the first part is already true.

&& is the opposite, in the since that the second part does not get executed unless the first part is true.

what does the vertical bar character do at the beginning of a method definition's name

'"|" being used at the beginning of a method definition' indeed defines the method |.

What are those pipe symbols for in Ruby?

They are the variables yielded to the block.

def this_method_takes_a_block
yield(5)
end

this_method_takes_a_block do |num|
puts num
end

Which outputs "5". A more arcane example:

def this_silly_method_too(num)
yield(num + 5)
end

this_silly_method_too(3) do |wtf|
puts wtf + 1
end

The output is "9".

Print Horizontal Line in Ruby

I use a quick puts "*"*80 for debug purposes. I'm sure there are better ways.

What does |f| do in Ruby?

In your code, you are passing two variables to the comma method. The first is a symbol called :show_mytable and the second is a block. It is unrelated to the ||= syntax which is conditional assignment.

Here is an example of how blocks are used in ruby:

array = [1, 2, 3, 4]
array.each do |element|
element + 1
end
#=> 2 3 4 5

When you use a loop(each in this case), you can pass it a variable(element) to give you a way to reference the current element in the loop.

You can also use curly braces instead of do and end like this:

array = [1, 2, 3, 4]
array.each { |e| e + 1 }
#=> 2 3 4 5

Since you aren't looping through anything here I don't see any reason you could need the |f| in your example.

What does ||= (or-equals) mean in Ruby?

This question has been discussed so often on the Ruby mailing-lists and Ruby blogs that there are now even threads on the Ruby mailing-list whose only purpose is to collect links to all the other threads on the Ruby mailing-list that discuss this issue.

Here's one: The definitive list of ||= (OR Equal) threads and pages

If you really want to know what is going on, take a look at Section 11.4.2.3 "Abbreviated assignments" of the Ruby Language Draft Specification.

As a first approximation,

a ||= b

is equivalent to

a || a = b

and not equivalent to

a = a || b

However, that is only a first approximation, especially if a is undefined. The semantics also differ depending on whether it is a simple variable assignment, a method assignment or an indexing assignment:

a    ||= b
a.c ||= b
a[c] ||= b

are all treated differently.



Related Topics



Leave a reply



Submit