Re: writeln the struct from the alis this Example from the home page

2021-11-19 Thread Martin Tschierschke via Digitalmars-d-learn

On Thursday, 18 November 2021 at 16:08:22 UTC, Paul Backus wrote:
On Thursday, 18 November 2021 at 13:51:42 UTC, Martin 
Tschierschke wrote:

[...]


You can define a `toString` method, like this:

```d
string toString()
{
import std.conv;
return p.to!string;
}
```

You can find more information about `toString` in the 
documentation here: 
https://dlang.org/phobos/std_format_write.html


By the way, the reason your original version does not work is 
that `p` is `private`, so `writeln` cannot access it. If you 
change `p` to be `public`, it will work without a `toString` 
method.


Thank you, just removing ``private `` and it worked!


Nice example for operator overload resulting in readable linear algebra expressions

2021-11-19 Thread Martin Tschierschke via Digitalmars-d-learn

I just want to share a view lines of code.
The availability of operator overloading can result in very short 
and precise code for linear algebra.
To test/explore it a little I just modified the alias this 
example:

```
#!/usr/bin/env rdmd
struct Point
{
double[2] p;
// Forward all undefined symbols to p
alias p this;
auto opBinary(string op)(Point rhs)
{
static if (op == "+")
{
Point ret;
ret[0] = p[0] + rhs.p[0];
ret[1] = p[1] + rhs.p[1];
return ret;
}
else static if (op == "-")
{
Point ret;
ret[0] = p[0] - rhs.p[0];
ret[1] = p[1] - rhs.p[1];
return ret;
}
else static if (op == "*")
return p[0] * rhs.p[0] + p[1] * rhs.p[1];
else
static assert(0, "Operator " ~ op ~ " not 
implemented");

}
}

void main()
{
import std.stdio;// : writefln,write;

// Point behaves like a `double[2]` ...
Point p1, p2;
p1 = [2, 1], p2 = [1, 1];
// ... but with extended functionality
writef("p1*(p1 + p2) = %s*(%s + %s) =", p1, p1, p2);
write(p1 * (p1 + p2)); // compare this to code without 
operator overload:

}
```

Compare: ``p1 * (p1 + p2)`` to something with a structure like 
``dot(p1,(add(p1,p2)).``

(With the Dlangs UFCS it might become: ``p1.dot(p1.add(p2))`` )





Re: Are templated functions always re-constructed?

2021-11-19 Thread rempas via Digitalmars-d-learn

On Wednesday, 17 November 2021 at 17:02:45 UTC, H. S. Teoh wrote:


Regular (non-recursive) templates generally will not cause a 
noticeable change in compilation times.  The trouble usually 
only starts when you start using recursive templates.  Or when 
your templates are nested unreasonably deep (though this also 
usually only happens when there's recursive instantiation 
somewhere).



T


That's awesome! Thanks!


Why does this call the copy constructor 2 times and the assigment constructor once?

2021-11-19 Thread rempas via Digitalmars-d-learn
Hi! I'm trying to make my own string type for my library. Anyway, 
I'm not very experienced with structs/classes so I don't 
understand what's going one here. I will not post the full code 
because I don't think that anyone would like it so I will just 
post the important parts that play a role (tho in any case feel 
free to ask for the full code).


Code:
```
import core.memory;

import core.stdc.stdio;
import core.stdc.string;
import core.stdc.stdlib;

struct str {
private:
  char* _val;
  uint* _count;
  ulong _cap, _len;

public:
  // Constructors
  this(const char* val) {
printf("Debug: Called this(const char* val)\n");
this._val = cast(char*)val;
this._count = cast(uint*)pureMalloc(4);
*this._count = 0;
this._cap = 0;
this._len = strlen(val);
  }

  // Copy constructor
  this(ref return scope str rhs) {
printf("Debug: Copy constructor called!!! (strig rhs)\n");
this._cap = rhs.length;
this._len = this._cap;
this._val = cast(char*)pureMalloc(this._len);
strcpy(this._val, rhs.ptr);
this._count = cast(uint*)pureMalloc(4);
*this._count = 1;
  }

  // Assigment constructors
  str opAssign(str rhs) {
printf("Debug: Assigment constructor called!!! (str rhs)\n");
if (*this._count == 1) {
  free(this._val);
} else if (*this._count > 1) {
  (*this._count)--;
} else *this._count = 1;

this._val = cast(char*)pureMalloc(rhs.length);
if (!this._val) {
  fprintf(stderr, "Could not allocate memory for the str 
object");

  exit(1);
}

strcpy(this._val, rhs.ptr);
this._cap = rhs.length;
this._len = rhs.length;
return this;
  }

  @property char* ptr() { return _val; }
  @property ulong length() { return _len; }
}

extern (C) int main() {
  str name = "Mike";
  str other_name = "Anna";
  other_name = name;
  return 0;
}
```

So, when I assign the value of the variable "name" in the 
"other_name", first it will call the copy constructor, then it 
will call the assignment constructor and then it will call the 
copy constructor again. Why is this happening? I was expecting 
only the assignment constructor to get called.


Re: Why does this call the copy constructor 2 times and the assigment constructor once?

2021-11-19 Thread Paul Backus via Digitalmars-d-learn

On Friday, 19 November 2021 at 14:05:40 UTC, rempas wrote:
So, when I assign the value of the variable "name" in the 
"other_name", first it will call the copy constructor, then it 
will call the assignment constructor and then it will call the 
copy constructor again. Why is this happening? I was expecting 
only the assignment constructor to get called.


When you pass a struct instance to a function by value, or return 
a struct instance from a function by value, a copy is made, and 
the copy constructor is called.


Your `opAssign` takes `rhs` by value, and returns a `str` by 
value:


```d
// Returned by value
// |
// v
  str opAssign(str rhs) {
//  ^
//  |
// Passed by value
```

So, every call to it will result in two calls to `str`'s copy 
constructor.


If you want to avoid this, you can change `opAssign` to have the 
following signature:


```d
// Returned by referece
// |
// v
  ref str opAssign()(auto ref str rhs)
//   ^
//   |
// Passed by reference (if possible)
```

Since `auto ref` is only allowed for template functions, I have 
added an empty template argument list (the `()`) to make 
`opAssign` into a function template.


You can read more about [`ref` functions][1] and [`auto ref` 
parameters][2] in the D language specification.


[1]: https://dlang.org/spec/function.html#ref-functions
[2]: https://dlang.org/spec/template.html#auto-ref-parameters


Re: Why does this call the copy constructor 2 times and the assigment constructor once?

2021-11-19 Thread rempas via Digitalmars-d-learn

On Friday, 19 November 2021 at 14:22:07 UTC, Paul Backus wrote:


When you pass a struct instance to a function by value, or 
return a struct instance from a function by value, a copy is 
made, and the copy constructor is called.


Your `opAssign` takes `rhs` by value, and returns a `str` by

[...]

Since `auto ref` is only allowed for template functions, I have 
added an empty template argument list (the `()`) to make 
`opAssign` into a function template.


[...]


Interesting! It's weird that it works like that and explicitly 
calls a constructor but it indeed works as expected now. Thanks a 
lot and have an amazing day!


Null pointer in __vptr

2021-11-19 Thread frame via Digitalmars-d-learn
Got a suspicious interface instance in the debugger and question 
myself:


Is a null pointer entry in the __vptr[] valid or always a sign 
for corruption/wrong cast somewhere? thx


Re: Null pointer in __vptr

2021-11-19 Thread Adam D Ruppe via Digitalmars-d-learn

On Friday, 19 November 2021 at 15:37:59 UTC, frame wrote:
Is a null pointer entry in the __vptr[] valid or always a sign 
for corruption/wrong cast somewhere? thx


The `destroy` function (as well as other class destruction) will 
null out the whole vtable to help make use-after-free an obvious 
error. Possible that happened to you.


How to read a single character in D language?

2021-11-19 Thread BoQsc via Digitalmars-d-learn
Let's say I want to write a simple program that asks for an input 
of a single character.
After pressing a single key on a keyboard, the character is 
printed out and the program  should stop.


Efficient way to create/copy immutable struct instance with modified data

2021-11-19 Thread Merlin Diavova via Digitalmars-d-learn

Hi all,

I'm trying to figure out the most efficient way to create 
modified instances of immutable structs.


Currently, I'm doing the following:

```d
immutable struct Node {
string label;
Node parentNode;
NetworkPort port;

auto withLabel(string newLabel)
{
return Node(newLabel, this.parentNode, this.port);
}

auto withParentNode(Node newParentNode)
{
return Node(this.label, newParentNode, this.port);
}

auto withNetworkPort(NetworkPort newPort)
{
return Node(this.label, this.parentNode, newPort);
}
}
```
Coming from a scripting language the above makes the most sense.
In D, this an efficient way to do it? Are there any best 
practices around this?


Thanks in advance

Merlin


Re: How to read a single character in D language?

2021-11-19 Thread Adam D Ruppe via Digitalmars-d-learn

On Friday, 19 November 2021 at 17:36:55 UTC, BoQsc wrote:
Let's say I want to write a simple program that asks for an 
input of a single character.
After pressing a single key on a keyboard, the character is 
printed out and the program  should stop.


This is platform specific. About 10 lines of code for a minimum 
implementation per OS, but if you don't wanna do it that way my 
library has a function for it with a prepackaged sample:


http://arsd-official.dpldocs.info/arsd.terminal.html#single-key

that's arsd-official:terminal on dub or you can grab the file 
from my github repo.


I guess you could view my source to see the impl but I don't feel 
like pulling it out right now.


Re: Null pointer in __vptr

2021-11-19 Thread frame via Digitalmars-d-learn

On Friday, 19 November 2021 at 15:46:41 UTC, Adam D Ruppe wrote:

The `destroy` function (as well as other class destruction) 
will null out the whole vtable to help make use-after-free an 
obvious error. Possible that happened to you.


So, a partial nulled table shouldn't exist, right? like this:

__vptr[0]: address
__vptr[1]: 000
__vptr[2]: address
__vptr[3]: address
__vptr[4]: address
__vptr[5]: address
...

Because 0 should point to the object instance and next offsets 
are pointers to the member functions, correct?


Re: Efficient way to create/copy immutable struct instance with modified data

2021-11-19 Thread Adam D Ruppe via Digitalmars-d-learn

On Friday, 19 November 2021 at 17:38:53 UTC, Merlin Diavova wrote:
I'm trying to figure out the most efficient way to create 
modified instances of immutable structs.


This might not be the best way but it is a kinda cool trick 
anyway: structs have a `tupleof` property you can slice. So you 
can do things like:


Node(old_node.tupleof[0 .. argIndex], replacement, 
old_node.tupleof[argIndex + 1 .. $]);


Where argIndex can be like 0 to replace the first item in the 
struct, or 1 to replace the second.


It is possible to look this up using reflection and kinda 
automate this if you wanted.


```
mixin template Replaceable() {
// returns a replaced thing when you use it as 
`with_someField`
typeof(this) opDispatch(string s, T)(T replacement) 
if(s.length > 5 && s[0 .. 5] == "with_")

{
static foreach(idx, member; typeof(this).tupleof) 
{
static if(__traits(identifier, member) == 
s[5 .. $])

enum argIndex = idx;
}
// if the arg is not found you will get an ugly 
error message here about undefined

// argIndex meh.
return typeof(this)(this.tupleof[0 .. argIndex], 
replacement, this.tupleof[argIndex + 1 .. $]);

}
}

immutable struct Node {
string label;
Node* parentNode;
int port;

mixin Replaceable; // add the ugly generic code from the 
top

}

void main() {
Node i = Node("one", null, 4);
Node i2 = i.with_port(6); // and now use it like this
assert(i2.label == "one");
assert(i2.port == 6);
}
```


I did `with_` instead of camelCase to avoid having to mess with 
case comparisons on the name.


Re: Null pointer in __vptr

2021-11-19 Thread Adam D Ruppe via Digitalmars-d-learn

On Friday, 19 November 2021 at 18:04:17 UTC, frame wrote:

So, a partial nulled table shouldn't exist, right? like this:


Indeed.

I've gotten that before as a result of a compiler bug... I had an 
abstract method that wasn't implemented but the compile time 
error got swallowed by a bug and thus the null method made its 
way to the binary.


I think that bug was fixed but still you might want to check 
your code for the `abstract` keyword and ensure they are legit 
implemented in your cases.




Re: Null pointer in __vptr

2021-11-19 Thread frame via Digitalmars-d-learn

On Friday, 19 November 2021 at 18:14:03 UTC, Adam D Ruppe wrote:

I've gotten that before as a result of a compiler bug... I had 
an abstract method that wasn't implemented but the compile time 
error got swallowed by a bug and thus the null method made its 
way to the binary.


You got it! It was an abstract class involved and the method 
signature was just wrong, but no compile error. Thanks!




Re: How to read a single character in D language?

2021-11-19 Thread BoQsc via Digitalmars-d-learn

On Friday, 19 November 2021 at 18:01:57 UTC, Adam D Ruppe wrote:

On Friday, 19 November 2021 at 17:36:55 UTC, BoQsc wrote:
Let's say I want to write a simple program that asks for an 
input of a single character.
After pressing a single key on a keyboard, the character is 
printed out and the program  should stop.


This is platform specific. About 10 lines of code for a minimum 
implementation per OS, but if you don't wanna do it that way my 
library has a function for it with a prepackaged sample:


http://arsd-official.dpldocs.info/arsd.terminal.html#single-key

that's arsd-official:terminal on dub or you can grab the file 
from my github repo.


I guess you could view my source to see the impl but I don't 
feel like pulling it out right now.


Thanks Adam.
I've tested and it does work on Windows 10.


mkdir "read_character_project"
cd "read_character_project"
dub init
dub add arsd-official:terminal
notepad ./source/app.d


import arsd.terminal;

void main() {
auto terminal = Terminal(ConsoleOutputType.linear);
	auto input = RealTimeConsoleInput(&terminal, 
ConsoleInputFlags.raw);


terminal.writeln("Press any key to continue...");
auto ch = input.getch();
terminal.writeln("You pressed ", ch);
}



dub run


Performing "debug" build using C:\Program Files\LDC 
1.28\bin\ldc2.exe for x86_64.
arsd-official:terminal 10.3.10: target for configuration "normal" 
is up to date.
arsd ~master: target for configuration "application" is up to 
date.

To force a rebuild of up-to-date targets, run again with --force.
Running arsd.exe
Press any key to continue...
You pressed u

___

Of interest, I also tried to look up getch() inside
http://arsd-official.dpldocs.info/source/arsd.terminal.d.html#L2867

But the source file overwhelmed me by its size.

For now I'm still interested in a more simple standalone 
implementation that would be more learning friendly, or at least 
with little explanation of basic things behind the code and how 
it is interfacing with the operating system, the native library.




Re: Null pointer in __vptr

2021-11-19 Thread Ali Çehreli via Digitalmars-d-learn

On 11/19/21 10:04 AM, frame wrote:
> On Friday, 19 November 2021 at 15:46:41 UTC, Adam D Ruppe wrote:
>
>> The `destroy` function (as well as other class destruction) will null
>> out the whole vtable to help make use-after-free an obvious error.
>> Possible that happened to you.
>
> So, a partial nulled table shouldn't exist, right? like this:
>
> __vptr[0]: address
> __vptr[1]: 000
> __vptr[2]: address
> __vptr[3]: address
> __vptr[4]: address
> __vptr[5]: address
> 
>
> Because 0 should point to the object instance

I am not sure that's correct. The way I picture it, the code reaches the 
__vptr by following a pointer; so it's already known. Additionally, I am 
under the impression that there is only one __vptr for a given type, 
which all class objects of that type point to.


> and next offsets are pointers to the member functions, correct?

My understanding is that all entries are that.

Ali



Re: How to read a single character in D language?

2021-11-19 Thread Adam Ruppe via Digitalmars-d-learn

On Friday, 19 November 2021 at 20:51:09 UTC, BoQsc wrote:

But the source file overwhelmed me by its size.


Yeah, the getch function in there builds on the rest of the 
events the library offers, so it won't be that useful outside.



The OS functions for getch alone though are actually pretty 
simple:


1) change the terminal to "raw" mode. the default is to buffer 
lines, which means your application doesn't get anything until a 
line is complete. You need to turn that off.


The RealTimeConsoleInput constructor does this in the lib:
http://arsd-official.dpldocs.info/v10.3.8/source/arsd.terminal.d.html#L2487

On Windows, you basically just call `SetConsoleMode`, but since 
the console is a shared resource, you also need to save the old 
mode to set it back later (that's what I do in the destructor of 
the struct).


On Linux, you call `tcsetattr`. The function for mine is here:
http://arsd-official.dpldocs.info/v10.3.8/source/arsd.terminal.d.html#L2620

Again, the terminal is a shared resource (this is actually even 
more true on linux systems!) so it is important to save the old 
one and set it back when you're done. There's a lot of ways this 
can happen so you should handle them all - that's why there's a 
bunch of signal handler blocks there.


Other things the library initialize is if you want echo, mouse 
input, paste events, resize notifications, etc. But if you only 
care about getch you can ignore most that stuff.


2) Read the terminal's event stream. On Windows, you call 
`ReadConsoleInput` and process the struct it sends you for a 
keyevent. See: 
http://arsd-official.dpldocs.info/v10.3.8/source/arsd.terminal.d.html#L3122


On Linux, you call the system `read` function on the stdin stream 
(file number 0). Basic keys will come as a single byte read on 
there. Others get extremely complicated.

http://arsd-official.dpldocs.info/v10.3.8/source/arsd.terminal.d.html#L3369

And it goes on for about 400 lines! And it depends on some of 
that other initialization we skipped over before and uses a 
database of terminal quirks found elsewhere in the file.


Windows' API is far, far easier to use.


But the Linux one isn't bad if you only want basic alphanumeric 
and enter keys. You can read those as a single ascii byte off the 
read function, so for that you can do it in just a few lines.


3) Again, remember to set it back how you found it before you 
exit by callling the SetConsoleMode/tcsetattr again before you 
exit.


Re: Any additions for write-to-file short program

2021-11-19 Thread pascal111 via Digitalmars-d-learn

On Thursday, 18 November 2021 at 23:09:28 UTC, H. S. Teoh wrote:
On Thu, Nov 18, 2021 at 10:20:48PM +, pascal111 via 
Digitalmars-d-learn wrote:
In next program that rewrites original written texts into new 
files, I see that it may need some additions or we can accept 
it like this because it's just a simple program that achieve 
its task and doesn't need any philosophical additions.


I assume there's a reason you're reading the input file by line 
instead of just copying it using larger fixed-size blocks?  
Perhaps you have in mind some kind of line-based filtering or 
processing eventually?


Because for copying a file, using a large, fixed-size block 
will work much faster. Not to mention the code will be simpler. 
For example:


auto inputFile = File(inputFilename, "r");
auto outputFile = File(outputFilename, "w");

enum bufferSize = 8194;
	inputFile.byChunk(bufferSize)	// read input in blocks of 8194 
bytes
		.copy(outputFile.lockingBinaryWriter); // copy each block 
into output file



T



When I compiled the code after adding yours, I found this error 
message:


"untitled20.d:24:8: error: no property 'copy' for type 'ByChunk'
   24 |.copy(outputFile.lockingBinaryWriter); // copy 
each block into output file

  |^
"





Re: How to read a single character in D language?

2021-11-19 Thread Imperatorn via Digitalmars-d-learn

On Friday, 19 November 2021 at 17:36:55 UTC, BoQsc wrote:
Let's say I want to write a simple program that asks for an 
input of a single character.
After pressing a single key on a keyboard, the character is 
printed out and the program  should stop.


If you want to test on Windows you can do this:

```d
// conio.h
extern (C) int _getch();
```

Like for demonstration purposes:
```d
writeln("Press a button...");
int a = _getch();
writeln("You pressed ", a);
```

That should be unbuffered.


Re: Any additions for write-to-file short program

2021-11-19 Thread Imperatorn via Digitalmars-d-learn

On Friday, 19 November 2021 at 22:21:52 UTC, pascal111 wrote:

On Thursday, 18 November 2021 at 23:09:28 UTC, H. S. Teoh wrote:

[...]



When I compiled the code after adding yours, I found this error 
message:


"untitled20.d:24:8: error: no property 'copy' for type 'ByChunk'
   24 |.copy(outputFile.lockingBinaryWriter); // copy 
each block into output file

  |^
"


Did you import std.algorithm?


Re: How to read a single character in D language?

2021-11-19 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Nov 19, 2021 at 10:21:42PM +, Adam Ruppe via Digitalmars-d-learn 
wrote:
[...]
> The OS functions for getch alone though are actually pretty simple:
> 
> 1) change the terminal to "raw" mode. the default is to buffer lines,
> which means your application doesn't get anything until a line is
> complete. You need to turn that off.
[...]
> 2) Read the terminal's event stream.
[...]
> 3) Again, remember to set it back how you found it before you exit by
> callling the SetConsoleMode/tcsetattr again before you exit.

And *this* is why you want to use a library for this.  Doing this by
hand is certainly possible, but very tedious, error-prone, and requires
a lot of knowledge about OS system calls.  Why bother when you could
just drop arsd.terminal into your workspace and call it a day?  :-)

(Of course, learning how things work under the hood for the sake of
educating yourself is definitely worthwhile. Just don't do that when you
need to get stuff done.)


T

-- 
Let's not fight disease by killing the patient. -- Sean 'Shaleh' Perry


Re: Any additions for write-to-file short program

2021-11-19 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Nov 19, 2021 at 10:21:52PM +, pascal111 via Digitalmars-d-learn 
wrote:
[...]
> When I compiled the code after adding yours, I found this error message:
> 
> "untitled20.d:24:8: error: no property 'copy' for type 'ByChunk'
>24 |.copy(outputFile.lockingBinaryWriter); // copy each block
> into output file
>   |^
> "

import std.algorithm;


T

-- 
It is impossible to make anything foolproof because fools are so ingenious. -- 
Sammy


Re: Any additions for write-to-file short program

2021-11-19 Thread pascal111 via Digitalmars-d-learn

On Friday, 19 November 2021 at 23:05:03 UTC, H. S. Teoh wrote:
On Fri, Nov 19, 2021 at 10:21:52PM +, pascal111 via 
Digitalmars-d-learn wrote: [...]
When I compiled the code after adding yours, I found this 
error message:


"untitled20.d:24:8: error: no property 'copy' for type 
'ByChunk'
   24 |.copy(outputFile.lockingBinaryWriter); // copy 
each block

into output file
  |^
"


import std.algorithm;


T


Thanks! it works now.

code:

// D programming language

import std.stdio;
import std.string;
import std.algorithm;

int main()
{

string s;
char[] f;


try{
write("Enter file name and path: ");
readln(f);
f=strip(f);


File inputFile = File(f, "r");
File outputFile = File("output_x", "w");

enum bufferSize = 8194;
inputFile.byChunk(bufferSize)	// read input in blocks of 8194 
bytes
   .copy(outputFile.lockingBinaryWriter); // copy each block 
into output file



inputFile.close();
outputFile.close();
}


catch(Exception err){
stderr.writefln!"Warning! %s"(err.msg);
return 1;
}



return 0;

}


Re: Dub says that there is an invalid semVer format, but I don't see how.

2021-11-19 Thread Ruby The Roobster via Digitalmars-d-learn
On Friday, 12 November 2021 at 21:22:32 UTC, Ruby The Roobster 
wrote:
On Thursday, 11 November 2021 at 01:57:10 UTC, rikki cattermole 
wrote:


On 11/11/2021 2:13 PM, Ruby The Roobster wrote:

Branch ~master: Invalid SemVer format: testing.0.0
Branch ~testing: Invalid SemVer format: testing.0.0
Version 0.1.2: Invalid SemVer format: testing.0.0


testing is a branch.

You are using ~>testing for it.

To use a branch in the SEMVER is ~branch.

https://dub.pm/package-format-json.html#version-specs


This was not causing me issues before. It worked until I added 
the v0.1.2 tag.


This seems to be a dead thread, but I always get these errors:

Branch ~master: Invalid SemVer format: testing.0.0
Branch ~stable: Invalid SemVer format: stable.0.0


Re: Dub says that there is an invalid semVer format, but I don't see how.

2021-11-19 Thread rikki cattermole via Digitalmars-d-learn



Don't use ~> for branches.

alpha@DESKTOP-RB97SA4 /tmp/dutils
$ dub build
Invalid SemVer format: stable.0.0

alpha@DESKTOP-RB97SA4 /tmp/dutils
$ nano dub.json

alpha@DESKTOP-RB97SA4 /tmp/dutils 

$ dub build 

Performing "debug" build using 
C:\Tools\D\dmd_2.097.2\windows\bin\dmd.exe for x86_64. 

dutils 0.1.2-beta.2+commit.9.g359c59d: building configuration 
"library"... 

Error: module `package` is in file 'package.d' which cannot be read 

import path[0] = source 

import path[1] = C:\Tools\D\dmd_2.097.2\windows\bin\..\..\src\phobos 

import path[2] = 
C:\Tools\D\dmd_2.097.2\windows\bin\..\..\src\druntime\import 

C:\Tools\D\dmd_2.097.2\windows\bin\dmd.exe failed with exit code 1. 




alpha@DESKTOP-RB97SA4 /tmp/dutils 

$ cat dub.json 

{ 

"authors": [ 

"Ruby The Roobster" 

], 

"copyright": "Copyright © 2021, Ruby The Roobster", 

"description": "A collection of modules in the D Programming 
Language that people may find useful.", 

"license": "GLP-3.0", 

"name": "dutils", 

"importPaths": ["./source"], 

"sourceFiles": ["package.d"], 

"targetType": "library", 

"subPackages": [ 

{ 

"name": "sprite", 

"description": ".spr file format for images 
because I'm to lazy to use a preexisting one for sprites.", 

"targetType": "library", 

"importPaths": ["./source"], 

"sourceFiles": ["sprite.d"], 

"dependencies": { 

"dutils:skeleton": "~stable" 

} 

}, 

{ 

"name": "binom", 

"description": "Module for doing some bionomial 
work in the D Programming Language(why did I make this).",
"targetType": "library", 

"importPaths": ["./source"], 

"sourceFiles": ["binom.d"] 

}, 

{ 

"name": "skeleton", 

"description": "Module for implementing 
skeletons, e.g. a cube with criss-crossing beams to better detect 
collision.",
"targetType": "library", 

"importPaths": ["./source"], 

"sourceFiles": ["skeleton.d"] 

}, 

{ 

"name": "physics", 

"description": "A very simple and basic physics 
library.",
"targetType": "library", 

"importPaths": ["./source"], 

"sourceFiles": ["physics.d"], 

"dependencies": { 

"dutils:skeleton": "~stable" 

} 

} 

] 

}