A better way to introspect a capture

Richard Hainsworth

I want to test the type of the first object in a signature. The following shows some ways I have found that work. But why does a smart match on a Type (2nd of the 3 tests below) not work? Is there a better way than stringifying and testing for the string equivalent of the Type? (Below is the use case I am working on)

raku -e "sub a( |c ) { say so |c[0].WHAT.raku ~~ /'Rat'/, so |c[0].WHAT ~~ Rat, so |c[0].^name ~~ /'Rat'/ };a(3/2);a(2)"
TrueFalseTrue
FalseFalseFalse
# OUTPUT:
#TrueFalseTrue
#FalseFalseFalse

I am writing a proto sub handle, and most of the subs have similar signatures, eg. multi sub handle( Pod $node, MyObj $p, Int $level --> Str)

So most of the multi subs do different things depending on what is in $node. However, how to handle cases when the handle is called with Nil or a plain string. I am thinking about something like

proto handle(|c) {
    if |c[0].^name ~~ /'Str'/ { # code for string }
    else { {*} }
}
raiph

A better way to introspect ...

In general, a better way to do anything in any programming language is to not introspect if you can avoid it.

In general, in Raku, you can avoid manual introspection. See the section Introspection toward the end of this answer for further discussion.

... a capture

The best tool for getting the functionality that introspection of a capture provides is to use a signature. That's their main purpose in life.

I want to test the type of the first object in a signature

Use signatures:

proto handle(|) {*}
multi handle( Pod $node )   { ... }
multi handle( Str $string ) { ... }
multi handle( Nil )         { ... }

The following shows some ways I have found that work.

While they do what you want, they are essentially ignoring all of Raku's signature features. They reduce the signature to just a binding to the capture as a single structure; and then use manual introspection of that capture in the routine's body.

There's almost always a simpler and better way to do such things using signatures.

why does [|c[0].WHAT ~~ Rat, with c[0] == 3/2] not work?

I'll simplify first, then end up with what your code is doing:

say    3/2        ~~ Rat;  # True
say   (3/2)       ~~ Rat;  # True
say   (3/2).WHAT  ~~ Rat;  # True
say |((3/2).WHAT  ~~ Rat); # True
say (|(3/2).WHAT) ~~ Rat;  # False
say  |(3/2).WHAT  ~~ Rat;  # False

The last case is because | has a higher precedence than ~~.

Is there a better way than stringifying and testing for the string equivalent of the Type?

OMG yes.

Use the types, Luke.

(And in your use case, do so using signatures.)

Introspection

Compared to code that manually introspects incoming data in the body of a routine, appropriate use of signatures will typically:

  • Read better;

  • Generate better low-level code;

  • Be partially or fully evaluated during the compile phase.

If a language and its compiler have addressed a use case by providing a particular feature, such as signatures, then using that feature instead of introspection will generally lead to the above three benefits.

Languages/compilers can be broken into four categories, namely those that:

  1. Do not do or allow any introspection;

  2. Allow the compiler to introspect, but not devs;

  3. Allow both the compiler and devs to introspect, but aim to make it a last resort, at least for devs;

  4. Enable and encourage devs to introspect.

Raku(do) are in the third category. In the context of this SO, signatures are the primary feature that all but eliminates any need for a dev to manually introspect.

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Is there a better way of comparing dates

分類Dev

A better way to detect the cursor?

分類Dev

Better way to return boolean

分類Dev

Is there a better way to do this? BASH

分類Dev

better way to do this in MATLAB?

分類Dev

Is there a better way to loop code?

分類Dev

Is there a better way to define a global variable?

分類Dev

Decorator with Arguments: Would this be a better way?

分類Dev

Is this possible using LEAD or is there a better way?

分類Dev

Is there a way of making discord embeds better?

分類Dev

Is there a better way to do Insertion Sort?

分類Dev

Is there a better way to do this than echo?

分類Dev

Better way to override a function definition

分類Dev

Is there a better way to divide this string into substrings?

分類Dev

Is there a better way to re-use plots Matplotlib?

分類Dev

Better way of capturing multiple same tags?

分類Dev

Better way to execute nested for loops to generate a dict?

分類Dev

Better way of error handling in Kafka Consumer

分類Dev

rxJava better way to wait on a specific sequence of values

分類Dev

Which way of setting fields value is better and why?

分類Dev

Which way of setting fields value is better and why?

分類Dev

AngularJS: Is there a better way to achieve this than the one specified?

分類Dev

Better way to write jquery add/remove class

分類Dev

better way to load 2 dropdown in mvc

分類Dev

Better way to check a list for specific elements - python

分類Dev

Better way to pass bool variable as parameter?

分類Dev

What is a better way to write this SQL query?

分類Dev

Split vector at max value in Clojure -- better way?

分類Dev

Better way for concatenating two sorted list of integers

Related 関連記事

ホットタグ

アーカイブ