Alternative title: how does one "nicely" "update" the contents of text files with Kotlin?
I have seen how do i write to a file in kotlin.
Basically, the suggested solution there is based on creating a File object, to then write to it: File("somefile.txt").printWriter().use ...
But well: I already have code like this:
File(fname).bufferedReader().lineSequence().flatMap { transform(it) }
where transform() is my own method that either returns the original line, or some updates lines when some specific match matched. (its signature is transform(line : String) : Sequence<String>)
Sure: I could assign the result of flatMap() to some temporary variable, to then use that with printWriter().use.
But is there a nice, canonical way that works without a temporary variable?
Note that your reading code (File().bufferedReader().lineSequence()) can already be simplified to:
File(fname).useLines {
it.flatMap(::transform)
}
Now regarding writing without putting it in an intermediate variable...
File("writeTo").bufferedWriter().use { writer ->
File("readFrom").useLines { lines ->
lines.flatMap(::transform)
.forEach {
writer.appendln(it)
}
}
}
But I am not yet really convinced about it... I don't really like it ;-)
I rather like something like:
File("readFrom").useLines {
..
}.writeTo("writeTo")
but that is not going to work as long as I use useLines ;-)
But here is something similar:
File("readFrom").useLines {
it.flatMap(::transform)
.writeTo(File("writeTo"))
}
But this requires the following extension function then:
fun Sequence<String>.writeTo(file: File) {
file.bufferedWriter().use { writer -> forEach { writer.appendln(it) } }
}
On the other hand... I always wanted to have a sequence.toFile-writer ;-) adapted it already to use a delimiter as parameter...
Related
I have an object of $person as below:
$person = Person::where('id', $id)->first();
According to which $person exists or not I load other data:
if($person) {
$person->family_members = FamilyMemberController::FamilyMemberOf($person->id);
} else {
$person->family_members = [];
}
In the view file, I check the $person->family_members if not empty and exists to add a generated value :
if(!empty(array_filter($person->family_members))) {
// my code
}
But it throws an error:
array_filter(): Argument #1 ($array) must be of type array, Illuminate\Database\Eloquent\Collection given
I need to check this $person->family_members to make sure whether it's an array or a collection is not empty.
Writing code for if array do something if collection do something is the wrong way of implementation.
You can do two things.
use both returns as collection()
or either use both returns as an array[]
If collection
else {
$person->family_members = collect();
}
If array
use ->toArray() at the end of Eloquent. Check this answer
As well, I think you are confused with array_filter(). Maybe you are searching for in_array() or contains()
Use count method
if(count($person->family_members)>0){
//your code
}
We don't know your code, but given the error, it's safe to assume your method returns a Collection. You can see available methods in the docs. However, if you need it as array, all you need to do is call ->toArray() on the result Collection. Then you can use array_filter.
What about just doing
if(!$person->family_members){
// your code here
}
or
if($person->family_members){
// your code here
} else {
// code of "if it's empty" goes here
}
You can use the count() function to return a count of an index. ex
if(count($person->family_members)){
//do your true algo
}
Why you are using the empty method ?! Try this:
$person->family_members = $person ? FamilyMemberController::FamilyMemberOf($person->id) : null;
if($person->family_members){ // your code }
Try simple ways in Programming ;)
I created some classes with Ruby's C API. I want to create a function whose behavior will change depending on the class of the Ruby object.
I tried to use is_a? from Ruby, however, I don't think it's the good way to do this. I checked "Creating Extension Libraries for Ruby" without success. The only direct way to check classes is with the default types.
I have my class "Klass" already created:
VALUE rb_cKlass = rb_define_class("Klass", rb_cObject);
And how I wanted to check if the class is the good one:
VALUE my_function(VALUE self, VALUE my_argument) {
if(rb_check_class(my_argument), rb_cKlass)) {
// do something if my_argument is an instance of Klass
} else {
return Qnil;
}
}
Is there a way to do this?
I came across this recently, and used the RBASIC_CLASS macro, but was getting segfaults in certain scenarios for some unexplained reason.
After scanning through ruby.h, I found the CLASS_OF macro, which returns the class as VALUE of a given object.
VALUE obj = INT2NUM(10);
VALUE klass = CLASS_OF(obj); // rb_cInteger
Using Ruby 2.5
Every ruby object is internally represented by RObject struct (I will copy the source here for the sake of future readers):
struct RObject {
struct RBasic basic;
union {
struct {
uint32_t numiv;
VALUE *ivptr;
void *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
} heap;
VALUE ary[ROBJECT_EMBED_LEN_MAX];
} as;
};
The very first member, RBasic, defines the class:
struct RBasic {
VALUE flags;
const VALUE klass;
}
To get an access to RBasic metadata of anything, one might use RBASIC macro:
RBASIC(my_argument)
To get the class directly, one might use RBASIC_CLASS macro:
RBASIC_CLASS(my_argument)
If you want to stay close to the is_a? Ruby fashion (i.e. check if any of the ancestors is the expected class), you could directly use the C implementation of is_a?, rb_obj_is_kind_of:
rb_obj_is_kind_of(my_argument, rb_cKlass) // Qtrue OR Qfalse
And since Qfalse == 0, you can just use that method as a condition:
VALUE my_function(VALUE self, VALUE my_argument) {
if(rb_obj_is_kind_of(my_argument, rb_cKlass)) {
// do something if my_argument is an instance of Klass
} else {
return Qnil;
}
}
To find this method, just check Object#is_a? documentation and click to toggle source, you'll see the C implementation if it is a C function (hence this will work for most of the standard lib).
I have details like below in an array. There will be plenty of testbed details in actual case. I want to grep a particular testbed(TESTBED = vApp_eprapot_icr) and an infomation like below should get copied to another array. How can I do it using perl ? End of Testbed info can be understood by a closing flower bracket }.
TESTBED = vApp_eprapot_icr {
DEVICE = vApp_eprapot_icr-ipos1
DEVICE = vApp_eprapot_icr-ipos2
DEVICE = vApp_eprapot_icr-ipos3
DEVICE = vApp_eprapot_icr-ipos5
CARDS=1GIGE,ETHFAST
CARDS=3GIGE,ETHFAST
CARDS=10PGIGE,ETHFAST
CARDS=20PGIGE,ETHFAST
CARDS=40PGIGE,ETHFAST
CARDS=ETHFAST,ETHFAST
CARDS=10GIGE,ETHFAST
CARDS=ETH,ETHFAST
CARDS=10P10GIGE,ETHFAST
CARDS=PPA2GIGE,ETHFAST
CARDS=ETH,ETHFAST,ETHGIGE
}
I will make it simpler, please see the below array
#array("
student=Amit {
Age=20
sex=male
rollno=201
}
student=Akshaya {
Age=24
phone:88665544
sex=female
rollno=407
}
student=Akash {
Age=23
sex=male
rollno=356
address=na
phone=88456789
}
");
Consider an array like this. Where such entries are plenty. I need to grep, for an example student=Akshaya's data. from the opening '{' to closing '}' all info should get copied to another array. This is what I'm looking for.
while (<>) {
print if /TESTBED = vApp_eprapot_icr/../\}/;
}
as a sidenote <> will capture the filename you use on cmdline. So if the data is stored in a file you will run from commandline
perl scriptname.pl filename.txt
Ok. We finally have enough information to come up with an answer. Or, at least, to produce two answers which will work on slightly different versions of your input file.
In a comment you say that you are creating your array like this:
#array = `cat $file`;
That's not a very good idea for a couple of reasons. Firstly, why run an external command like cat when Perl will read the file for you. And secondly, this gives you one element in your array for each line in your input file. Things become far easier if you arrange it so that each of your TESTBED = foo { ... } records is a single array element.
Let's get rid of the cat first. The easiest way to read a single file into an array is to use the file input operator - <>. That will read data from the file whose name is given on the command line. So if you call your program filter_records, you can call it like this:
$ ./filter_records your_input_data.txt
And then read it into an array like this:
#array = <>;
That's good, but we still have each line of the input file in its own array element. How we fix that depends on the exact format of your input file. It's easiest if there's a blank line between each record in the input file, so it looks like this:
student=Amit {
Age=20
sex=male
rollno=201
}
student=Akshaya {
Age=24
phone:88665544
sex=female
rollno=407
}
student=Akash {
Age=23
sex=male
rollno=356
address=na
phone=88456789
}
Perl has a special variable called $/ which controls how it reads records from input files. If we set it to be an empty string then Perl goes into "paragraph" mode and it uses blank lines to delimit records. So we can write code like this:
{
local $/ = '';
#array = <>;
}
Note that it's always a good idea to localise changes to Perl's special variables, which is why I have enclosed the whole thing in a naked block.
If there are no blank lines, then things get slightly harder. We'll read the whole file in and then split it.
Here's our example file with no blank lines:
student=Amit {
Age=20
sex=male
rollno=201
}
student=Akshaya {
Age=24
phone:88665544
sex=female
rollno=407
}
student=Akash {
Age=23
sex=male
rollno=356
address=na
phone=88456789
}
And here's the code we use to read that data into an array.
{
local $/;
$data = <>;
}
#array = split /(?<=^})\n/m, $data;
This time, we've set $/ to undef which means that all of the data has been read from the file. We then split the data wherever we find a newline that is preceded by a } on a line by itself.
Whichever of the two solutions above that we use, we end up with an array which (for our sample data) has three elements - one for each of the records in our data file. It's then simple to use Perl's grep to filter that array in various ways:
# All students whose names start with 'Ak'
#filtered_array = grep { /student=Ak/ } #array;
If you use similar techniques on your original data file, then you can get the records that you are interested in with code like this:
#filtered_array = grep { /TESTBED = vApp_eprapot_icr/ } #array;
I'm trying to learn D and I thought after doing the hello world stuff, I could try something I wanted to do in Java before, where it was a big pain because of the way the Regex API worked: A little template engine.
So, I started with some simple code to read through a file, character by character:
import std.stdio, std.file, std.uni, std.array;
void main(string [] args) {
File f = File("src/res/test.dtl", "r");
bool escape = false;
char [] result;
Appender!(char[]) appender = appender(result);
foreach(c; f.rawRead(new char[f.size])) {
if(c == '\\') {
escape = true;
continue;
}
if(escape) {
escape = false;
// do something special
}
if(c == '#') {
// start of scope
}
appender.put(c);
}
writeln(appender.data());
}
The contents of my file could be something like this:
<h1>#{hello}</h1>
The goal is to replace the #{hello} part with some value passed to the engine.
So, I actually have two questions:
1. Is that a good way to process characters from file in D? I hacked this together after searching through all the imported modules and picking what sounded like it might do the job.
2. Sometimes, I would want to access more than one character (to improve checking for escape-sequences, find a whole scope, etc. Should I slice the array for that? Or are D's regex functions up to that challenge? So far, I only found matchFirst and matchAll methods, but I would like to match, replace and return to that position. How could that be done?
D standard library does not provide what you require. What you need is called "string interpolation", and here is a very nice implementation in D that you can use the way you describe: https://github.com/Abscissa/scriptlike/blob/4350eb745531720764861c82e0c4e689861bb17e/src/scriptlike/core.d#L139
Here is a blog post about this library: https://p0nce.github.io/d-idioms/#String-interpolation-as-a-library
The question pretty much sums it up. "dtrace 'print an associative array'" has exactly one google hit and the similar searches are equally useless.
EDIT:
If I were to use an aggregation, I'm not aware that I'd still be able to remove entries. My application requires that I be able to do things like:
file_descriptors[0] = "stdin"
file_descriptors[3] = "service.log"
...
...
file_descriptors[3] = 0
...
...
# should print only those entries that have not been cleared.
print_array(file_descriptors)
I know that you can clear an entire aggregation, but what about a single entry?
UPDATE:
Since I'm doing this in OS X and my application is to track all of the file descriptors that have been opened by a particular process, I was able to have an array of 256 pathnames, thusly:
syscall::open*:entry
/execname == $1/
{
self->path = copyinstr(arg0);
}
syscall::open*:return
/execname == $1/
{
opened[arg0] = self->path;
}
syscall::close*:entry
/execname == $1/
{
opened[arg0] = 0;
}
tick-10sec
{
printf(" 0: %s\n", opened[0]);
}
The above probe repeated 255 more times...
It sucks. I'd really like to have something better.
Is this the link Google found? Because the advice seems pretty sound:
I think the effect you're looking for should be achieved by using an
aggregation rather than an array. So you'd actually do something like:
#requests[remote_ip,request] = count();
... and then:
profile:::tick-10sec
{
/* print all of the requests */
printa(#requests);
/* Nuke the requests aggregation */
trunc(#requests);
}
Use an associative array and sum(1) and sum(-1) instead of count().