What Does <<Desc Mean in Ruby

What does DESC mean in ruby?

It is used to create multiline strings. Basically, '<< DESC' tells ruby to consider everything that follows until the next 'DESC' keyword. 'DESC' is not mandatory, as it can be replaced with anything else.

a = <<STRING
Here
is
a
multiline
string
STRING

The << operator is followed by an identifier that marks the end of the document. The end mark is called the terminator. The lines of text prior to the terminator are joined together, including the newlines and any other whitespace.
http://en.wikibooks.org/wiki/Ruby_Programming/Here_documents

What is the magic behind desc 'description' on rake?

Imagine simple DSL that has a state (very naïve implementation):

@tasks = []
@current = nil

def desc text
@current = Task.new(desc: text)
end

def task params, &cb
@current.update(params)
yield
....
@tasks << @current
@current = nil
end

The code above requires additional checks etc, but the idea is that: stateful DSL collects tasks with their descriptions.

Ruby |= assignment operator

Bitwise OR assignment.

x |= y

is shorthand for:

x = x | y

(just like x += y is shorthand for x = x + y).

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 is the mean of * and flatten in ruby

The * is called the "splat operator"; I'm not sure I could give you the technical definition (though I'm sure you'd find it soon enough with Google's help), but the way I'd describe it is that it basically takes the place of hand-writing multiple comma-separated values in code.

To make this more concrete, consider the case of Hash[] which you've used in your example. The Hash class has a [] class method which takes a variable number of arguments and can normally be called like this:

# Returns { "foo" => 1, "bar" => 2 }
h = Hash["foo", 1, "bar", 2]

Notice how that isn't an array or a hash or anything that I passed in; it's a (hand-written) sequence of values. The * operator allows you to achieve basically the same thing using an array--in your case, the one returned by movie_popularity.sort_by{|m,p| p}.reverse.flatten.

As for that flatten call: when you call sort_by on a hash, you're really leveraging the Enumerable module which is included in a variety of classes (most notably Array and Hash) that provide enumeration. In the case of a hash, you've probably noticed that instead of iterating over one like this:

hash.each { |value| ... }

Instead you do this:

hash.each { |key, value| ... }

That is, iterating over a hash yields two values on each iteration. So your sort_by call on its own would return a sequence of pairs. Calling flatten on this result collapses the pairs into a one-dimensional sequence of values, like this:

# Returns [1, 2, 3, 4]
[[1, 2], [3, 4]].flatten

Ruby: Can I write multi-line string with no concatenation?

There are pieces to this answer that helped me get what I needed (easy multi-line concatenation WITHOUT extra whitespace), but since none of the actual answers had it, I'm compiling them here:

str = 'this is a multi-line string'\
' using implicit concatenation'\
' to prevent spare \n\'s'

=> "this is a multi-line string using implicit concatenation to eliminate spare
\\n's"

As a bonus, here's a version using funny HEREDOC syntax (via this link):

p <<END_SQL.gsub(/\s+/, " ").strip
SELECT * FROM users
ORDER BY users.id DESC
END_SQL
# >> "SELECT * FROM users ORDER BY users.id DESC"

The latter would mostly be for situations that required more flexibility in the processing. I personally don't like it, it puts the processing in a weird place w.r.t. the string (i.e., in front of it, but using instance methods that usually come afterward), but it's there. Note that if you are indenting the last END_SQL identifier (which is common, since this is probably inside a function or module), you will need to use the hyphenated syntax (that is, p <<-END_SQL instead of p <<END_SQL). Otherwise, the indenting whitespace causes the identifier to be interpreted as a continuation of the string.

This doesn't save much typing, but it looks nicer than using + signs, to me.

Also (I say in an edit, several years later), if you're using Ruby 2.3+, the operator <<~ is also available, which removes extra indentation from the final string. You should be able to remove the .gsub invocation, in that case (although it might depend on both the starting indentation and your final needs).

EDIT: Adding one more:

p %{
SELECT * FROM users
ORDER BY users.id DESC
}.gsub(/\s+/, " ").strip
# >> "SELECT * FROM users ORDER BY users.id DESC"

What does __FILE__ mean in Ruby?

It is a reference to the current file name. In the file foo.rb, __FILE__ would be interpreted as "foo.rb".

Edit: Ruby 1.9.2 and 1.9.3 appear to behave a little differently from what Luke Bayes said in his comment. With these files:

# test.rb
puts __FILE__
require './dir2/test.rb'
# dir2/test.rb
puts __FILE__

Running ruby test.rb will output

test.rb
/full/path/to/dir2/test.rb

What does that line of code do?

Can someone explain how this simple line of code line_items << item do all that stuff?

That line doesn't do all that.

This could be better read like this:

def add_line_items_from_cart(cart)   #<-- For each item that we transfer from the cart to the order we need to do two things
cart.line_items.each do |item|
item.cart_id = nil #<-- First we set the cart_id to nil in order to prevent the item from going poof when we destroy the cart.
line_items << item #<-- Then we add the item itself to the line_items collection for the order
end
end

The remaining:

Notice that we didn’t have to do anything special with... etc. etc

Is info about what the framework does. So, the description corresponds to the whole piece of code and not only to that line.

class self idiom in Ruby

First, the class << foo syntax opens up foo's singleton class (eigenclass). This allows you to specialise the behaviour of methods called on that specific object.

a = 'foo'
class << a
def inspect
'"bar"'
end
end
a.inspect # => "bar"

a = 'foo' # new object, new singleton class
a.inspect # => "foo"

Now, to answer the question: class << self opens up self's singleton class, so that methods can be redefined for the current self object (which inside a class or module body is the class or module itself). Usually, this is used to define class/module ("static") methods:

class String
class << self
def value_of obj
obj.to_s
end
end
end

String.value_of 42 # => "42"

This can also be written as a shorthand:

class String
def self.value_of obj
obj.to_s
end
end

Or even shorter:

def String.value_of obj
obj.to_s
end

When inside a function definition, self refers to the object the function is being called with. In this case, class << self opens the singleton class for that object; one use of that is to implement a poor man's state machine:

class StateMachineExample
def process obj
process_hook obj
end

private
def process_state_1 obj
# ...
class << self
alias process_hook process_state_2
end
end

def process_state_2 obj
# ...
class << self
alias process_hook process_state_1
end
end

# Set up initial state
alias process_hook process_state_1
end

So, in the example above, each instance of StateMachineExample has process_hook aliased to process_state_1, but note how in the latter, it can redefine process_hook (for self only, not affecting other StateMachineExample instances) to process_state_2. So, each time a caller calls the process method (which calls the redefinable process_hook), the behaviour changes depending on what state it's in.



Related Topics



Leave a reply



Submit