How to define a global function dependent on a local pattern? [duplicate]

When g is in the local scope defined by Block, the following fails:

Block[{g, x},
g[x] = StringExpression[x : LetterCharacter];
SetAttributes[f, Listable];
f = Function[{str}, StringMatchQ[str, g[x]], Listable];
]


eg. f[{"v", "e", "7", "2", "i"}] produces the message StringExpression::invld with text "Element g[x] is not a valid string or pattern element in g[x]" and returns

{StringMatchQ["v", g[x]], StringMatchQ["e", g[x]],
StringMatchQ["7", g[x]], StringMatchQ["2", g[x]],
StringMatchQ["i", g[x]]}


but instead when g is in the global scope ie when g is removed from the list of variables that are local to the Block, f works as expected.

On the previous example, evaluating f[{"v", "e", "7", "2", "i"}] returns {True, True, False, False, True}.

(Why is this happening and) would it be possible to make f work when g is local to the Block?

marked as duplicate by Kuba♦May 3 '18 at 9:01

• Function is HoldAll and once Block is done there is no reference to g which is inside f. You need to inject it with With or Function[...] /. DownValues[g] – Kuba May 3 '18 at 8:31
• @Kuba thanks! With doesn't work with g[x] but /. DownValues[g] does the trick; a quick follow-up: when I define f as in SetAttributes[f, Listable]; f[str_] := StringMatchQ[str, g[x]], the problem persists for the same reasons? – user42582 May 3 '18 at 8:57
• Yes, because SetDelayed holds right hand side too. – Kuba May 3 '18 at 9:01