less / less/less.js

Unexpected extracted variable in second looped ruleset

Open
#3,647 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
JavaScript
Stars
17k
Forks
3.4k
Avg merge
7h 42m
Merged PRs (30d)
26

Description

A variable extracted from a list has a different value than expected, but not during the first mixin loop.

An example is:

@list: red, blue, green;

.loop(@rules, @index: length(@list)) when (@index > 0) {
  @el: extract(@list, @index);
  
  @rules();
  
  .loop(@rules, @index - 1);
}

.loop({
  .a { 
    color: @el;
  }
});

.loop({
  .b { 
    background-color: @el;
  }
});

I expect three .a and three .b with the three different colors but I get (https://lesscss.org/less-preview/ 2021-09-09):

.a {
  color: green;
}
.a {
  color: blue;
}
.a {
  color: red;
}
.b {
  background-color: green;
}
.b {
  background-color: green;
}
.b {
  background-color: green;
}

Checking the value before the @rules(); call, I get the expected color:

  .test {
    current: @el;
  }
  @rules();
.test {
  current: green;
}
.a {
  color: green;
}
.test {
  current: blue;
}
.a {
  color: blue;
}
.test {
  current: red;
}
.a {
  color: red;
}
.test {
  current: green;
}
.b {
  background-color: green;
}
.test {
  current: blue;
}
.b {
  background-color: green;
}
.test {
  current: red;
}
.b {
  background-color: green;
}

Adding index: @index; near current, color and background-color has always the expected values.
Only the extracted @el is fixed in the second loop.

Since @list and @index are correct during the ruleset evaluation, if I extract the value inside the ruleset it works as expected:

.loop({
  @el: extract(@list, @index);
  .b {
    background-color: @el;
  }
});
.b {
  background-color: green;
}
.b {
  background-color: blue;
}
.b {
  background-color: red;
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the recursive Less mixin reproduction in the issue and compare the first loop's extracted @el with the second loop's behavior around @rules(). Check the alternate example that extracts @el inside the ruleset. Done means the original example emits green, blue, and red for both .a and .b rules.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.