ruby: what does the asterisk in p *1..10 mean
It's the splat operator. You'll often see it used to split an array into parameters to a function.
def my_function(param1, param2, param3)
param1 + param2 + param3
end
my_values = [2, 3, 5]
my_function(*my_values) # returns 10
More commonly it is used to accept an arbitrary number of arguments
def my_other_function(to_add, *other_args)
other_args.map { |arg| arg + to_add }
end
my_other_function(1, 6, 7, 8) # returns [7, 8, 9]
It also works for multiple assignment (although both of these statements will work without the splat):
first, second, third = *my_values
*my_new_array = 7, 11, 13
For your example, these two would be equivalent:
p *1..10
p 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Difference between '..' (double-dot) and '...' (triple-dot) in range generation?
The documentation for Range† says this:
Ranges constructed using
..
run from the beginning to the end inclusively. Those created using...
exclude the end value.
So a..b
is like a <= x <= b
, whereas a...b
is like a <= x < b
.
Note that, while to_a
on a Range of integers gives a collection of integers, a Range is not a set of values, but simply a pair of start/end values:
(1..5).include?(5) #=> true
(1...5).include?(5) #=> false
(1..4).include?(4.1) #=> false
(1...5).include?(4.1) #=> true
(1..4).to_a == (1...5).to_a #=> true
(1..4) == (1...5) #=> false
†The docs used to not include this, instead requiring reading the Pickaxe’s section on Ranges. Thanks to @MarkAmery (see below) for noting this update.
What does to_proc method mean in Ruby?
Some methods take a block, and this pattern frequently appears for a block:
{|x| x.foo}
and people would like to write that in a more concise way. In order to do that they use a combination of: a symbol, the method Symbol#to_proc
, implicit class casting, and &
operator. If you put &
in front of a Proc
instance in the argument position, that will be interpreted as a block. If you combine something other than a Proc
instance with &
, then implicit class casting will try to convert that to a Proc
instance using to_proc
method defined on that object if there is any. In case of a Symbol
instance, to_proc
works in this way:
:foo.to_proc # => ->x{x.foo}
For example, suppose you write:
bar(&:foo)
The &
operator is combined with :foo
, which is not a Proc
instance, so implicit class cast applies Symbol#to_proc
to it, which gives ->x{x.foo}
. The &
now applies to this and is interpreted as a block, which gives:
bar{|x| x.foo}
What is Ruby Coverage.c is and what is it for?
The "number of line execution" is, as you might expect, the number of times a line has been executed by the interpreter during execution of the program.
Let's look at the example in the documentation with the results added to the original code as comments.
[foo.rb]
s = 0 # executed once
10.times do |x| # once
s += x # ten times
end # not analyzed
# not analyzed
if s == 45 # once
p :ok # once
else # not analyzed
p :ng # not executed
end # not analyzed
[EOF]
require "coverage.so"
Coverage.start
require "foo.rb"
p Coverage.result #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]}
The "coverage" is the analysis of how many times each line is executed.
I assume that this module would be useful to see if you have decent "code coverage" with your tests, i.e. check if the tests actually go through all the code or if there are parts that are never executed.
Using the same example in that context, this coverage analysis tells you that the else p :ng
part is not exectued and might not be tested.
What does Ruby have that Python doesn't, and vice versa?
You can have code in the class definition in both Ruby and Python. However, in Ruby you have a reference to the class (self). In Python you don't have a reference to the class, as the class isn't defined yet.
An example:
class Kaka
puts self
end
self in this case is the class, and this code would print out "Kaka". There is no way to print out the class name or in other ways access the class from the class definition body in Python.
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
The *args
and **kwargs
is a common idiom to allow arbitrary number of arguments to functions as described in the section more on defining functions in the Python documentation.
The *args
will give you all function parameters as a tuple:
def foo(*args):
for a in args:
print(a)
foo(1)
# 1
foo(1,2,3)
# 1
# 2
# 3
The **kwargs
will give you all
keyword arguments except for those corresponding to a formal parameter as a dictionary.
def bar(**kwargs):
for a in kwargs:
print(a, kwargs[a])
bar(name='one', age=27)
# name one
# age 27
Both idioms can be mixed with normal arguments to allow a set of fixed and some variable arguments:
def foo(kind, *args, **kwargs):
pass
It is also possible to use this the other way around:
def foo(a, b, c):
print(a, b, c)
obj = {'b':10, 'c':'lee'}
foo(100,**obj)
# 100 10 lee
Another usage of the *l
idiom is to unpack argument lists when calling a function.
def foo(bar, lee):
print(bar, lee)
l = [1,2]
foo(*l)
# 1 2
In Python 3 it is possible to use *l
on the left side of an assignment (Extended Iterable Unpacking), though it gives a list instead of a tuple in this context:
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
Also Python 3 adds new semantic (refer PEP 3102):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
For example the following works in python 3 but not python 2:
>>> x = [1, 2]
>>> [*x]
[1, 2]
>>> [*x, 3, 4]
[1, 2, 3, 4]
>>> x = {1:1, 2:2}
>>> x
{1: 1, 2: 2}
>>> {**x, 3:3, 4:4}
{1: 1, 2: 2, 3: 3, 4: 4}
Such function accepts only 3 positional arguments, and everything after *
can only be passed as keyword arguments.
Note:
- A Python
dict
, semantically used for keyword argument passing, are arbitrarily ordered. However, in Python 3.6, keyword arguments are guaranteed to remember insertion order. - "The order of elements in
**kwargs
now corresponds to the order in which keyword arguments were passed to the function." - What’s New In Python 3.6 - In fact, all dicts in CPython 3.6 will remember insertion order as an implementation detail, this becomes standard in Python 3.7.
Related Topics
Heroku Gem Not Working with Rvm
How to Stop the Rails Debugger for the Current Request
Binary String Literals in Ruby 2.0
Declaring Instance Variables Iterating Over a Hash!
How to Call Rake Tasks That Are Defined in the Standard Rakefile from an Other Ruby Script
Does Sublime Text Have Support for Ruby API (Auto-Complete)
Suitability of Rails, Padrino, and Sinatra for Building a Prepaid Mobile Service
Rails 3: Generate Unique Codes (Coupons)
How to Check If a Number Is Included in a Range (In One Statement)
Best Practice About Empty Belongs_To Association
Cool Tricks and Expressive Snippets with Ruby Collections/Enumerables
Testing Whether String Starts with or End with Another String
Most Concise Way to Test String Equality (Not Object Equality) for Ruby Strings or Symbols
How to Use "Gets" on a Rake Task
How to Delete All Contents of a Folder with Ruby-Rails
How to Convert an Existing Rails 3 Application into an Engine