Converting match object to string in perl6 - string

I was trying to convert a match object to a string in perl6. The method Str on a match object is defined as:
method Str(Match:D: --> Str:D)
I would think I could use Str($match) to accomplish this. And it seems to convert it to a string, but I'm getting an error using the string with the following code:
my $searchme = "rudolph";
my $match = $searchme ~~ /.*dol.*/;
say $match.WHAT;
my $test1 = Str($match);
say $test1.WHAT;
say $test1;
With the output:
(Match)
(Str)
With the error:
Cannot find method 'gist': no method cache and no .^find_method in
block at .code.tio line 6
However, if I run:
my $searchme = "rudolph";
my $match = $searchme ~~ /.*dol.*/;
say $match.WHAT;
my $test1 = $match.Str;
say $test1.WHAT;
say $test1;
I get no error and the result:
(Match)
(Str)
rudolph
Is this a bug or me misunderstanding how it works?
Thanks for reading.

I'm writing this up as an answer even though it's actually an incomplete discussion of a bug, so not at all normal SO fare. The alternative of lots of comments doesn't seem better.
It's a bug. Perhaps you just golfed this.
dd $test1; instead of say $test1; is helpful in that it displays BOOTStr $test1 = (BOOTStr without .perl method).
Based on that I searched the rakudo repo for BOOTStr and that led to the above issue.
Golfing it further leads to:
say $ = Str(Match.new);
Note that these are all fine:
say Str(Match.new);
say $ = Int(Match.new);
say $ = Str(Date.new: '2015-12-31');
It appears to be a combination of leaking some implementation details regarding how Rakudo/NQP/MoarVM bootstrap; Match being an NQP object; Str() on that being wonky; and assigning it to a Scalar container (the $ is an anonymous one) making that wonkiness visible.
I'll add more when/if I figure it out.

Related

using variable to define a char in MATLAB

I have a variable
filterSize = 3; %Size of the Filter;
I want to define a new char variable called size and assign it as
size = (filterSize x filterSize)
size='3x3';
but I want to use filterSize to do it to automate. size need to be char. Thanks
You can use sprintf to format a char containing variables
filterSize = 3;
sz = sprintf( '%dx%d', filterSize, filterSize );
You should avoid using size as a variable name because you're shadowing a commonly used in-built function.
I have solved the problem.
size_temp = [string(filterSize),'x',string(filterSize)];
a = convertStringsToChars(size_temp);
x=char(size_temp(1));
y=char(size_temp(2));
z=char(size_temp(3));
size = [x,y,z]
but as cris Luengo suggests in the comments
size = [num2str(filterSize),'x', num2str(filterSize)] is a better solution
MATLAB has a function that precisely does what you asked for:
.
call generic example :
evalin('base',['output = ',expression])
MATLAB funtion help reference :
https://uk.mathworks.com/help/matlab/ref/evalin.html?s_tid=srchtitle_evalin_1
Assigning a value to new variable within your code has detractors and supporters, as it is a sharp tool that writes new code with code.
I had a couple of bitter discussions with a Mathworks forum member over different ways to use evalin.
When some one preaches not to do something because they call it sinful yet they keep doing it all the time, there's room for doubt that people in general should refrain to use evalin to concisely build new code within existing code.
I recommend you to ignore the last line in evalin help page where some one discourages from using evalin to exactly do what you need to in order to solve your question.
Hope it helps

Print Element GString Property in Human Readable format

I'm writing a rust application with a simple gstreamer pipeline. I would like to print the stats property of the appsink element in a human readable format.
With this code:
let stats = appsink.get_property("stats").unwrap();
println!("stats: {:?}", stats);
I get:
stats: Value(GString(Foreign(0x7f9c008f00, 101)))
Since that isn't human readable, I tried:
let stats = appsink.get_property("stats").unwrap().get::<GString>();
println!("stats: {:?}", stats);
but got:
stats: Err(GetError { actual: GstStructure, requested: gchararray })
I'm not sure how to interpret the output.
I've looked at this post: gstreamer rust get human readable output for bitrate set on x264enc but it doesn't show how to approach a GString.
I was able to sort of reproduce this using the following example:
use gstreamer::prelude::*;
fn main() {
gstreamer::init().unwrap();
let source = gstreamer::ElementFactory::make("videotestsrc", Some("source")).expect("Could not create source element.");
let val = source.get_property("pattern").unwrap();
println!("{:?}", val);
}
This will attempt to get the pattern property on a generic VideoTestSrc element, and it will print out the string address instead of the actual string. Adding .get::<GString>() to the let val statement will produce a runtime error:
Err(GetError { actual: GstVideoTestSrcPattern, requested: gchararray })
which is telling us that it tried to cast to gchararray but the actual data type of the property is a custom type, GstVideoTestSrcPattern, which is not a string. In your example, the property value has the type GstStructure. It might be possible to use .get::<GstVideoTestSrcPattern>() to get the value of the pattern property and manipulate it as such, but since we want a string here, there's another way using the .transform() method defined on a glib::Value:
let val = source.get_property("pattern").unwrap().transform::<String>().unwrap().get::<String>().unwrap().unwrap();
This is rather unwieldy and it would be advised to do a lot more error checking on the values returned here (for example using the ? operator instead of the .unwrap()s).
The .transform::<String>() call will try to give us a String representation of the property's value, but it gives us a Option<Value> which we must unwrap and convert into an actual String using .get::<String>(), which gives us a Result<Option<String>, GetError> (the inner option is because the string could be NULL). Unwrapping those values gives us a printable string.
There might be a simpler way, but this at least gives you the result. There is more documentation on how to deal with glib Value types here: https://gstreamer.pages.freedesktop.org/gstreamer-rs/glib/value/struct.Value.html
But unfortunately it's not very easy to read and doesn't have examples. It might be possible to glean more info from the rust port of the gstreamer tutorials: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/tree/master/tutorials
Close to what transistor wrote, the correct way of doing this would be
let stats = appsink.get_property("stats").unwrap();
println!("stats: {:?}", stats.get::<gst::Structure>().expect("not a structure").expect("structure was None"));
You don't have to transform the glib::Value to a String, but you can directly get a gst::Structure from the glib::Value and work on that. Among other things it provides a Debug impl that allows direct printing of it, and various API for accessing the fields, etc. See https://gstreamer.pages.freedesktop.org/gstreamer-rs/gstreamer/structure/struct.StructureRef.htm

Updating a single field in a record with Haskell #

I need to update one field of a very large default record.
As the default may change I don't want to rebuild the entire record manually.
Now I have come across the following way of doing this, but I am not sure how it works:
unaggregate :: MyResult -> MyResult
unaggregate calc#MyResult{..} = calc{ the_defaults = the_override
`mappend` the_defaults }
where
the_override = create ("aggregation" := False)
I have tried searching for 'Haskell # operator' in Google but it does not return immediately useful information.
I saw somewhere calc#MyResult{..} does pattern matching on variables but I don't see what variable calc does for the MyResult record...
Also I have looked up mappend (and Monoids) and I am not sure how these work either...
Thank you for any help
The # symbol is called an "as-pattern". In the example above, you can use calc to mean the whole record. Usually you'd use it like this: calc#(MyResult someResult) -- so you can have both the whole thing and the pieces that you're matching. You can do the same thing with lists (myList#(myHead:myTail)) or tuples (myTuple#(myFst, mySnd). It's pretty handy!
MyResult{..} uses RecordWildcards. Which is a neat extension! BUT RecordWildcards doesn't help you update just one field of a record.
You can do this instead: calc { theFieldYouWantToUpdate = somethingNew }.

What do empty square brackets after a variable name mean in Groovy?

I'm fairly new to groovy, looking at some existing code, and I see this:
def timestamp = event.timestamp[]
I don't understand what the empty square brackets are doing on this line. Note that the timestamp being def'd here should receive a long value.
In this code, event is defined somewhere else in our huge code base, so I'm not sure what it is. I thought it was a map, but when I wrote some separate test code using this notation on a map, the square brackets result in an empty value being assigned to timestamp. In the code above, however, the brackets are necessary to get correct (non-null) values.
Some quick Googling didn't help much (hard to search on "[]").
EDIT: Turns out event and event.timestamp are both zero.core.groovysupport.GCAccessor objects, and as the answer below says, the [] must be calling getAt() on these objects and returning a value (in this case, a long).
The square brackets will invoke the underlying getAt(Object) method of that object, so that line is probably invoking that one.
I made a small script:
class A {
def getAt(p) {
println "getAt: $p"
p
}
}
def a = new A()
b = a[]
println b.getClass()
And it returned the value passed as a parameter. In this case, an ArrayList. Maybe that timestamp object has some metaprogramming on it. What does def timestamp contains after running the code?
Also check your groovy version.
Empty list, found this. Somewhat related/possibly helpful question here.
Not at a computer, but that looks like it's calling the method event.timestamp and passing an empty list as a parameter.
The same as:
def timestamp = event.timestamp( [] )

Wireshark dissector in Lua - userdata

I am new to Lua, and I am building a custom dissector for Wireshark. My situation is this:
The wireshark data consists of hex numbers such as 4321 8765 CBA9. What I would like to wind up with is (after it has been dissected) : CBA9 8765 4321.
What I have done so far is create a small function in Lua that will take these numbers individually, convert them to strings, and places them in the correct order.
function ReverseOrder3Numbers(hex_1, hex_2, hex_3)
local hex_1_int = hex_1:uint()
local hex_2_int = hex_2:uint()
local hex_3_int = hex_3:uint()
word1 = string.format("%04X", hex_1_int)
word2 = string.format("%04X", hex_2_int)
word3 = string.format("%04X", hex_3_int)
combined_string = "0x" .. word3 .. word2 .. word1
output = combined_string
return output
end
However, once I go to add this bunch to the tree, I get an error saying Lua Error: ...: calling 'add' on bad self (userdata expected, got string).
How can I get around this? Do I need a different approach entirely? I am not looking for anything complex or fancy. All I need to do is what I described. Any help would be appreciated.
There's nothing really wrong with ReverseOrder3Numbers (other than perhaps some missing local qualifiers). You should update your question to include the code that invokes add.
You might've accidentally used tree.add( ... ) instead of tree:add( ... ) (note the colon after tree).
Call tree:add() will send to the object 'tree' the direct link to 'tree' itself as first implicitly argument. And no matter how much args you will attach to this call or no one at all. Use tree.add() sintax if your 'add' method doesn't support self-link. In this case 'self' should be linked to the 'tree' object inside the 'add' method.
It's not clear what you pass to the function ReverseOrder3Numbers. But since you access theses parameeters with the uint method I assume that the parameters are tvb:range(x,y) results. If you want to change the order of the digits inside the individual values, you can use the endianess-aware methods:
function ReverseOrder3Numbers(hex_1, hex_2, hex_3)
local hex_1_int = hex_1:le_uint()
local hex_2_int = hex_2:le_uint()
local hex_3_int = hex_3:le_uint()
...
end
If you want to change the endianess of data that is added to the tree you should use the endianess-aware version of the add method.
tree:le_add(f_MyProtoField, tvb:range(x,y), ReverseOrder3Numbers(...))
I don't know the reason why le is suffix in the one case and a prefix in the other.

Resources