Get a symbol's value by its name in a sub

According to the documentation:

An initial :: doesn't imply global. Here as part of the interpolation syntax it doesn't even imply package. After the interpolation of the ::() component, the indirect name is looked up exactly as if it had been there in the original source code, with priority given first to leading pseudo-package names, then to names in the lexical scope (searching scopes outwards, ending at CORE).

So when you write say ::("$symbol") in dump_value() in the somelib package, it will first lookup $symbol in the current scope, which has value '$x' then try to look up $x (also in the current scope), but the variable $x is defined in the caller's lexical scope, so you get the No such symbol '$x' error.

You can refer to the caller's lexical symbol given by the value of $symbol using either:

CALLER::MY::($symbol);  # lexical symbols from the immediate caller's lexical scope

or

 CALLERS::($symbol); # Dynamic symbols in any caller's lexical scope

see the package documentation page.