Canonical solution of a scoping problem

Scoping is a recurrent issue on this forum.

Yet, I stumble again and again at the same thing. Googling over this site does not quickly bring a solution. Two reasons:

  1. There are many low quality answers such as this one (and I can
    elaborate on this, if needed).
  2. There are many very good answers (this and this), but they are too long.

Sometimes I just want to learn by examples, not by reading many pages of dry theory.
Therefore I would like to ask this question again even at risk being downvoted or the question being closed.

Consider this code

ClearAll(g,i,list);

list=Range(3)
g(l_):=Module({i},l/.{i_->2i})

g(list)
i=5
g(list)

Out(2)= {1,2,3}
Out(4)= {2,4,6}
Out(5)= 5
Out(6)= 10

Or a very similar one

ClearAll(g,i,list);

list=Range(3)
g(l_):=Cases(l,i_->2i)

g(list)
i=5
g(list)

Out(8)= {1,2,3}
Out(10)= {2,4,6}
Out(11)= 5
Out(12)= {10,10,10}

It is clear to me that setting the global variable i interferes with the function definition. I would like to know what is the canonical way of avoiding this interference?.

Please, avoid answer like 2 list. I am more expecting to see a discussion on the interplay of SetDelayed and RuleDelayed.