Difference Between '..' (Double-Dot) and '...' (Triple-Dot) in Range Generation

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 are the differences between double-dot .. and triple-dot ... in Git commit ranges?

It depends on whether you're using a log command or a diff command. In the log case, it's in the man git-rev-parse documentation:

To exclude commits reachable from a commit, a prefix ^ notation is used. E.g. ^r1 r2 means commits reachable from r2 but exclude the ones reachable from r1.

This set operation appears so often
that there is a shorthand for it. When
you have two commits r1 and r2 (named according to the syntax explained in
SPECIFYING REVISIONS above), you can
ask for commits that are reachable
from r2 excluding those that are
reachable from r1 by "^r1 r2" and it
can be written as "r1..r2".

A similar notation "r1...r2" is
called symmetric difference of r1 and
r2 and is defined as "r1 r2 --not
$(git merge-base --all r1 r2)". It is
the set of commits that are
reachable from either one of r1 or r2
but not from both.

Which basically means that you'll get all commits that are in either of the two branches, but not in both.

In the diff case, it's in the man git-diff documentation:

  git diff [--options] <commit>...<commit> [--] [<path>...]

This form is to view the changes on the branch containing and up to
the second <commit>, starting at a common ancestor of both
<commit>. "git diff A...B" is equivalent to "git diff
$(git-merge-base A B) B". You can omit any one of <commit>, which
has the same effect as using HEAD instead.

Which is a bit fuzzy. Basically it means it shows only the differences in that branch compared to another branch: it looks for the last common commit with the first committish you gave it, and then diffs the second committish to that. It's an easy way to see what changes are made in that branch, compared to this branch, without taking notice of changes in this branch only.

The .. is somewhat simpler: In the git-diff case, it's the same as a git diff A B and just diffs A against B. In the log case, it shows all commits that are in B but not in A.

Difference between 3-dot-range operator and 2-dot-range operator in flip flop ruby

The difference between 2 dots and 3 dots in Ruby is inclusion. For example

(1..100)
=> All numbers starting from 1 and ending at 100 INCLUDING 100

(1...100)
=> All numbers starting from 1 that are less than 100

(1..100).include?(100)
=> true

(1...100).include?(100)
=> false

Hope this helps.

What are the differences between double-dot .. and triple-dot ... in Git diff commit ranges?

Since I'd already created these images, I thought it might be worth using them in another answer, although the description of the difference between .. (dot-dot) and ... (dot-dot-dot) is essentially the same as in manojlds's answer.

The command git diff typically¹ only shows you the difference between the states of the tree between exactly two points in the commit graph. The .. and ... notations in git diff have the following meanings:

# Left side in the illustration below:
git diff foo..bar
git diff foo bar # same thing as above

# Right side in the illustration below:
git diff foo...bar
git diff $(git merge-base foo bar) bar # same thing as above

An illustration of the different ways of specifying commits for git diff<br>

In other words, git diff foo..bar is exactly the same as git diff foo bar; both will show you the difference between the tips of the two branches foo and bar. On the other hand, git diff foo...bar will show you the difference between the "merge base" of the two branches and the tip of bar. The "merge base" is usually the last commit in common between those two branches, so this command will show you the changes that your work on bar has introduced, while ignoring everything that has been done on foo in the mean time.

That's all you need to know about the .. and ... notations in git diff. However...


... a common source of confusion here is that .. and ... mean subtly different things when used in a command such as git log that expects a set of commits as one or more arguments. (These commands all end up using git rev-list to parse a list of commits from their arguments.)

The meaning of .. and ... for git log can be shown graphically as below:

An illustration of the different ways of specifying ranges of commits for git log

So, git rev-list foo..bar shows you everything on branch bar that isn't also on branch foo. On the other hand, git rev-list foo...bar shows you all the commits that are in either foo or bar, but not both. The third diagram just shows that if you list the two branches, you get the commits that are in either one or both of them.

Well, I find that all a bit confusing, anyway, and I think the commit graph diagrams help :)

¹ I only say "typically" since when resolving merge conflicts, for example, git diff will show you a three-way merge.

Is there any difference when defining a range with two dots and three dots in ruby?

A quick check:

(1..3).to_a
# => [1, 2, 3]
(1...3).to_a
# => [1, 2]

Its evident ... does not include the last value i.e. its the range till n-1.

Difference between .. and ... in Ruby

In ruby 1...5 gives you a range which doesn't include 5
whereas 1..5 gives you a range which does include 5

eg:

>> (1..5).to_a
[
[0] 1,
[1] 2,
[2] 3,
[3] 4,
[4] 5
]
>> (1...5).to_a
[
[0] 1,
[1] 2,
[2] 3,
[3] 4
]

Perl 6: Difference between .. and ...?

.. construct a range object (think mathematical interval).

... constructs a sequence (think lazily generated one-shot list).

If all I want to do is iterate over consecutive integers (eg for indexing), I prefer he former (it's the less general tool, and a character shorter to boot).

If you need more precise control, use the latter (eg the idiomatic example for generating the Fibonacci sequence in Perl6 is given by the expression 1, 1, *+* ... *, where he third term *+* is the rule for inductively generating the elements).

Native PHP functions that allow double-dot range syntax

Native PHP string functions that respect double-dot range expressions:

  • addcslashes() (Demo)

     echo addcslashes('adobe', 'a..e');
    // \a\do\b\e
  • chop() -- alias of rtrim() (Demo)

     echo chop('adobe', 'a..e');
    // ado
  • ltrim() (Demo)

     echo ltrim('adobe', 'a..e');
    // obe
  • rtrim() (Demo)

     echo rtrim('adobe', 'a..e');
    // ado
  • str_word_count() (Demo)

     var_export(
    str_word_count('do not break|on|pipe', 1, '{..}')
    );
    // ['do', 'not', 'break|on|pipe']
  • trim() (Demo)

     echo trim('adobe', 'a..e');
    // o
  • ucwords() (Demo)

     `echo ucwords('backdoorman', 'a..e');
    // BaCkdOormaN

Here are some native functions where ranged expressions are not expanded, but might be reasonable candidates for the feature:

  • strcspn() (Demo) (expansion would be reasonable)

     echo strcspn('cdplayer', 'b..e');
    // 6
    // 0 if range enabled
  • strpbrk() (Demo) (expansion would be reasonable)

     echo strpbrk('stackoverflow', 'b..f');
    // flow
    // ckoverflow if range enabled
  • strspn() (Demo) (expansion would be reasonable)

     echo strspn('adobe', 'a..e');
    // 1
    // 2 if range enabled
  • strtok() (Demo) (expansion would be reasonable)

     echo strtok('toddler', 'a..e');
    // toddl
    // to if range enabled
  • strtr() (Demo) (not a good candidate because character order matters)

     echo strtr('adobe', 'a..e', 'A..E');
    // AdobE
    // ADoBE if range enabled

How does Ruby's range and triple equals (===) work?

1895..1913 === 1895 is the same as 1895..(1913 === 1895), and what you want is (1895..1913) === 1895.

See Ruby Operator Precedence.



Related Topics



Leave a reply



Submit