4

I have a variable of type value that stores a map, but I can not access the values by providing the keys:

rascal>a
value: ("s":"s")

rascal>a["s"]
|stdin:///|(2,3,<1,2>,<1,5>): subscript not supported on value at |stdin:///|(2,3,<1,2>,<1,5>)
☞ Advice

How can I parse the value to map in order to be able to retrieve my value ?

  • There is the question of how you got this map in the first place :-) So you could also prevent this from happening, for example when you read a value from disk use `readTextValueFile(#map[str,str], myLoc)`. This will guarantee the return value to be of type `map[str,str]` – Jurgen Vinju Nov 26 '13 at 16:13
  • 1
    or you reused the a variable in the console, and due to lubbing it becomes a value. – Davy Landman Nov 26 '13 at 20:23
  • does that answer your question Santiago? – Jurgen Vinju Dec 03 '13 at 15:17

1 Answers1

6
if (map[str,str] myMap := a) {
   // do stuff with myMap
}
else {
  throw "<a> is not a map?";
}

Another way of "narrowing types" is using pattern matching in function parameters:

rascal>value x = 1;
int: 1
rascal>int myFunc(int i) = 2 * i;
ok
rascal>myFunc(x);
int: 2

And yet another way is using visit or switch:

visit(bigValue) {
  case Expression e => ...work with e...
}

The general idea is:

  • pattern matching means narrowing (downcasting)
  • pattern matching may fail and so is always in a conditional context
  • there are many places in Rascal where you can use pattern matching: function dispatch, switch, visit, :=, <-
Jurgen Vinju
  • 6,393
  • 1
  • 15
  • 26
  • Worked very well! Thanks Jurgen. To add upon the other comments below the main post. Sometimes you cannot avoid it! You have to get direct info out of an AST tree and then you stumble across a 'value' type. This comment saved my hours :) – Jorrick Sleijster Mar 07 '18 at 00:03
  • 1
    For completeness: This code snippet is implemented in Rascal as the typeCast function (see https://www.rascal-mpl.org/docs/library/type/#Type-typeCast) – Linus Wagner Nov 29 '22 at 14:01
  • I often avoid this by using pattern matching directly, so in a `visit(bla) { case MyType e: ... }` the pattern matching is already done by the `case` pattern, even though the `bla` is of type `value`. Also function parameters can be used like this: `int myFunction(MyPattern e)` can be applied to any value, but it will only match for `MyPattern` and so you can avoid to write a "cast" pattern like my answer. – Jurgen Vinju Nov 29 '22 at 14:02