www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std_exception.html#enforce: example does not compile

reply kdevel <kdevel vogtner.de> writes:
https://dlang.org/phobos/std_exception.html#enforce and also 
https://dlang.org/library/std/exception/enforce.html present this 
example:

---
auto f = enforce(fopen("data.txt"));
auto line = readln(f);
enforce(line.length, "Expected a non-empty line.");
---

fopen, readln and enforce need imports, fopen needs a mode 
parameter:

enforce.d
---
import core.stdc.stdio : fopen;
import std.stdio : readln;
import std.exception;

void main ()
{
    auto f = enforce(fopen("data.txt", "r"));
    auto line = readln(f);
    enforce(line.length, "Expected a non-empty line.");
}
---

$ dmd enforce
enforce.d(7): Error: function expected before (), not module 
enforce of type void

According to https://tour.dlang.org/tour/en/basics/exceptions I 
changed the import (not knowing why):

enforce.d
---
import core.stdc.stdio : fopen;
import std.stdio : readln;
import std.exception : enforce;

void main ()
{
    auto f = enforce(fopen("data.txt", "r"));
    auto line = readln(f);
    enforce(line.length, "Expected a non-empty line.");
}
---

Now I get:

$ dmd enforce
enforce.d(8): Error: template std.stdio.readln cannot deduce 
function from argument types !()(shared(_IO_FILE)*), candidates 
are:
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3921):        
std.stdio.readln(S = string)(dchar terminator = '\x0a') if 
(isSomeString!S)
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3955):        
std.stdio.readln(C)(ref C[] buf, dchar terminator = '\x0a') if 
(isSomeChar!C && is(Unqual!C == C) && !is(C == enum))
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3962):        
std.stdio.readln(C, R)(ref C[] buf, R terminator) if 
(isSomeChar!C && is(Unqual!C == C) && !is(C == enum) && 
isBidirectionalRange!R && is(typeof(terminator.front == 
(dchar).init)))

What's wrong here? And why is the "selective import" of enforce 
necessary?
Jan 27
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, January 27, 2018 13:29:00 kdevel via Digitalmars-d-learn wrote:
 What's wrong here? And why is the "selective import" of enforce
 necessary?
Because you named your module enforce. As such, by default, referring to enforce inside of the module refers to the module. Having the selective import overrides that. It's generally not a good idea to name your module the same name something that you would refer to inside the module. It's usually not an issue in real programs, because in that case, aside from maybe the module with main, modules aren't at the top-level, but if you're doing something like naming your test program after a function that you're using in it, you're going to have problems. - Jonathan M Davis
Jan 27
parent reply kdevel <kdevel vogtner.de> writes:
On Saturday, 27 January 2018 at 16:10:29 UTC, Jonathan M Davis 
wrote:
 On Saturday, January 27, 2018 13:29:00 kdevel via 
 Digitalmars-d-learn wrote:
 What's wrong here? And why is the "selective import" of 
 enforce necessary?
Because you named your module enforce. As such, by default, referring to enforce inside of the module refers to the module. Having the selective import overrides that.
Okay. But what about that persisting error message: zz.d --- import core.stdc.stdio : fopen; import std.stdio : readln, writeln; import std.exception; // : enforce; void main () { auto f = enforce(fopen("data.txt", "r")); auto line = readln(f); enforce(line.length, "Expected a non-empty line."); } --- $ dmd zz zz.d(8): Error: template std.stdio.readln cannot deduce function from argument types !()(shared(_IO_FILE)*), candidates are: /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3921): std.stdio.readln(S = string)(dchar terminator = '\x0a') if (isSomeString!S) /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3955): std.stdio.readln(C)(ref C[] buf, dchar terminator = '\x0a') if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum)) /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3962): std.stdio.readln(C, R)(ref C[] buf, R terminator) if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) && isBidirectionalRange!R && is(typeof(terminator.front == (dchar).init))) The example still does not compile.
Jan 27
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, January 27, 2018 17:57:54 kdevel via Digitalmars-d-learn wrote:
 On Saturday, 27 January 2018 at 16:10:29 UTC, Jonathan M Davis

 wrote:
 On Saturday, January 27, 2018 13:29:00 kdevel via

 Digitalmars-d-learn wrote:
 What's wrong here? And why is the "selective import" of
 enforce necessary?
Because you named your module enforce. As such, by default, referring to enforce inside of the module refers to the module. Having the selective import overrides that.
Okay. But what about that persisting error message: zz.d --- import core.stdc.stdio : fopen; import std.stdio : readln, writeln; import std.exception; // : enforce; void main () { auto f = enforce(fopen("data.txt", "r")); auto line = readln(f); enforce(line.length, "Expected a non-empty line."); } --- $ dmd zz zz.d(8): Error: template std.stdio.readln cannot deduce function from argument types !()(shared(_IO_FILE)*), candidates are: /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3921): std.stdio.readln(S = string)(dchar terminator = '\x0a') if (isSomeString!S) /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3955): std.stdio.readln(C)(ref C[] buf, dchar terminator = '\x0a') if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum)) /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3962): std.stdio.readln(C, R)(ref C[] buf, R terminator) if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) && isBidirectionalRange!R && is(typeof(terminator.front == (dchar).init))) The example still does not compile.
That has nothing to do with enforce. std.stdio.readln does not take a FILE*. In general, you shouldn't mix core.stdc.stdio and std.stdio. https://dlang.org/phobos/std_stdio.html#.readln readln has 3 overloads, all of which read from stdin. If you want to use readln on a file, then you need to use std.stdio.File and its member function, readln, not core.stdc.stdio.FILE. - Jonathan M Davis
Jan 27
parent reply kdevel <kdevel vogtner.de> writes:
On Saturday, 27 January 2018 at 18:34:35 UTC, Jonathan M Davis 
wrote:
 The example still does not compile.
That has nothing to do with enforce. std.stdio.readln does not take a FILE*. In general, you shouldn't mix core.stdc.stdio and std.stdio.
The code is from the official documentation: - https://dlang.org/phobos/std_exception.html#enforce, and - https://dlang.org/library/std/exception/enforce.html Shall I file a bug report?
Jan 27
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, January 27, 2018 20:11:29 kdevel via Digitalmars-d-learn wrote:
 On Saturday, 27 January 2018 at 18:34:35 UTC, Jonathan M Davis

 wrote:
 The example still does not compile.
That has nothing to do with enforce. std.stdio.readln does not take a FILE*. In general, you shouldn't mix core.stdc.stdio and std.stdio.
The code is from the official documentation: - https://dlang.org/phobos/std_exception.html#enforce, and - https://dlang.org/library/std/exception/enforce.html Shall I file a bug report?
Yes. Any time that code in the official docs doesn't compile, please report it. In most cases, the examples in the documentation are ddoc-ed unittest blocks, which catches such problems, but they aren't always. - Jonathan M Davis
Jan 27
parent reply kdevel <kdevel vogtner.de> writes:
On Saturday, 27 January 2018 at 20:33:46 UTC, Jonathan M Davis 
wrote:
 Shall I file a bug report?
Yes.
https://issues.dlang.org/show_bug.cgi?id=18319
Jan 27
parent Seb <seb wilzba.ch> writes:
On Saturday, 27 January 2018 at 21:27:44 UTC, kdevel wrote:
 On Saturday, 27 January 2018 at 20:33:46 UTC, Jonathan M Davis 
 wrote:
 Shall I file a bug report?
Yes.
https://issues.dlang.org/show_bug.cgi?id=18319
Thanks. Addressed and already merged: https://github.com/dlang/phobos/pull/6080 https://dlang.org/phobos-prerelease/std_exception.html#enforce
Jan 28