Re: Destruction Sequence: module and classes defined within

2010-10-06 Thread Lars T. Kyllingstad
On Tue, 05 Oct 2010 23:25:36 +0200, vano wrote:

 The code below:
  module used;
 
  import std.stdio;
 
  class ClassA {
  this()  { writeln(A ctor); }
  ~this() { writeln(A dtor); }
  }
 
  static this()  { writeln(used.sctor); } static ~this() {
  writeln(used.sdtor); }
 
  void main() {
  auto a = new ClassA();
  }
 produces the following output (DMD v2.049):
  used.sctor
  A ctor
  used.sdtor
  A dtor
 
 The question is: should the module be allowed to be unloaded before all
 module-level objects/structures are destructed/unloaded?


I'm no expert on this, but I think it has to be that way.  Consider this:

  class Foo { ... }
  Foo foo;

  static this()
  {
  foo = new Foo;
  }

  static ~this()
  {
  foo.doStuff();
  }

So you see, if foo had already been destroyed and garbage collected, my 
program would have crashed when the module static destructor was run.  
Thus, I guess, running the garbage collector for the final time has to be 
one of the last things done on program shutdown, after running all module 
destructors.

-Lars


Initialisation of static immutable arrays

2010-10-06 Thread Lars T. Kyllingstad
I have a program that uses an immutable array, the contents of which are 
known at compile time.  Thus, ideally, I want it to be placed in 
the .rodata segment of the program.

Firstly, I seem to remember reading that using an array literal in D will 
always result in a heap allocation.  Is this correct?

Secondly, if the above is not true, how can I verify that the array in 
the following piece of code isn't allocated and/or copied anew every time 
the program runs, or even worse, every time foo() is called?

  void foo()
  {
  static immutable int[3] = [1, 2, 3];
  }

I know, RTFAsm, but some help with that would be appreciated. ;)

Thirdly, intuition tells me that when the array is immutable, the 
'static' shouldn't have an effect.  But experiments (i.e. printing the 
adress of the array) indicate that it does.  Is there some reason for 
this, or is it just a shortcoming of the compiler?

-Lars


Re: Initialisation of static immutable arrays

2010-10-06 Thread Lars T. Kyllingstad
On Wed, 06 Oct 2010 10:16:45 +, Lars T. Kyllingstad wrote:

   static immutable int[3] = [1, 2, 3];

..should of course be

  static immutable int[3] a = [1, 2, 3];

-Lars


Re: Associative arrays give compile error

2010-10-06 Thread Steven Schveighoffer
On Tue, 05 Oct 2010 22:02:30 -0400, bearophile bearophileh...@lycos.com  
wrote:



Denis Koroskin:


Compute mutable copy and then cast to immutable. Am I missing something?


That's possible. But it's an exceptionally dirty thing, I am not sure it  
works in SafeD. A well designed const system has to offer a more clean  
solution :-) Do you agree?


Casting to immutable is the only way to create such a beast.  The best way  
to ensure as few bugs as possible is to create the object you wish to be  
immutable in a function, and cast at the end before returning.  This at  
least encapsulates the dirtiness in one function (which would probably be  
marked @trusted).


You can also use assumeUnique (which I'm guessing is there so it can be  
called in safeD?).


-Steve


Re: Initialisation of static immutable arrays

2010-10-06 Thread Steven Schveighoffer
On Wed, 06 Oct 2010 06:16:45 -0400, Lars T. Kyllingstad  
pub...@kyllingen.nospamnet wrote:



I have a program that uses an immutable array, the contents of which are
known at compile time.  Thus, ideally, I want it to be placed in
the .rodata segment of the program.

Firstly, I seem to remember reading that using an array literal in D will
always result in a heap allocation.  Is this correct?


Yes.  There is no way to create an immutable array besides a string in  
read only memory.  Even enums will result in array literals being created  
on the heap whenever you refer to them (there's a bug related to this  
somewhere).



Secondly, if the above is not true, how can I verify that the array in
the following piece of code isn't allocated and/or copied anew every time
the program runs, or even worse, every time foo() is called?

  void foo()
  {
  static immutable int[3] = [1, 2, 3];
  }


Actually, static probably will prevent it from being created every time  
foo is called.  I don't think there's a way to prevent it from being  
created every time the program is run.



I know, RTFAsm, but some help with that would be appreciated. ;)

Thirdly, intuition tells me that when the array is immutable, the
'static' shouldn't have an effect.  But experiments (i.e. printing the
adress of the array) indicate that it does.  Is there some reason for
this, or is it just a shortcoming of the compiler?


Of course.  If you realize that the expression [1,2,3] is not immutable,  
then it makes sense.


Another example to help you think about it:

void foo(int x)
{
   immutable int[3] = [1,2,x];
}

This must be run on every call of foo, because x can vary.

BTW, I'm all for making array literals immutable.  You can always make  
runtime-allocated arrays via a library function.


-Steve


Re: Initialisation of static immutable arrays

2010-10-06 Thread Denis Koroskin
On Wed, 06 Oct 2010 15:39:48 +0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:


BTW, I'm all for making array literals immutable.  You can always make  
runtime-allocated arrays via a library function.


-Steve


I second that!


Re: Associative arrays give compile error

2010-10-06 Thread bearophile
Steven Schveighoffer:

 Casting to immutable is the only way to create such a beast.

Then maybe we have to improve the language semantics to allow a better 
solution. See the Transients of Clojure or the larval objects of Java :-)

The compiler may need to test (at compile time) that there's only one reference 
to the AA and its contents, and turn it into immutable.

Bye,
bearophile


Using the llvm D-bindings

2010-10-06 Thread Manuel König
Hi,

did anyone have success using the llvm-2.7 D-bindings from the bindings
project http://www.dsource.org/projects/bindings on x86_64 linux? I
tried so far with ldc, but the compiler chokes about a mere 3570 lines
of unresolved symbols when linking with ldc, compiling works fine.

Short version:
==

I think the question boils down to How do I create a D library and
link it into a c++ program on x86_64 linux using ldc (or gdc or
any_other_D_compiler).

Long version:
=
Here's a snip of the linker error messages I get from ldc:

// -- file main.d
import llvm.c.Core;

void main()
{
auto context = LLVMGetGlobalContext();
}
// --

$ ldc -I=/path/to/llvm-2.7 \
-L=/usr/local/lib/libLLVM{Core,Support,System}.a main.d
/usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMContextCreate':
Core.cpp:(.text+0x57): undefined reference to `operator new(unsigned
long)'
/usr/local/lib/libLLVMCore.a(Core.o): In function
`LLVMModuleCreateWithName':
Core.cpp:(.text+0x13a): undefined reference to `operator new(unsigned
long)'
/usr/local/lib/libLLVMCore.a(Core.o): In function
`LLVMModuleCreateWithNameInContext':
Core.cpp:(.text+0x195): undefined reference to `operator new(unsigned
long)'
/usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMSetDataLayout':
Core.cpp:(.text+0x240): undefined reference to `std::basic_stringchar,
std::char_traitschar, std::allocatorchar ::basic_string(char
const*, unsigned long, std::allocatorchar const)'
Core.cpp:(.text+0x24f): undefined reference to `std::basic_stringchar,
std::char_traitschar, std::allocatorchar
::assign(std::basic_stringchar, std::char_traitschar,
std::allocatorchar  const)'
Core.cpp:(.text+0x25e): undefined reference to `std::basic_stringchar,
std::char_traitschar, std::allocatorchar
::_Rep::_S_empty_rep_storage'
Core.cpp:(.text+0x294): undefined reference to `std::basic_stringchar,
std::char_traitschar, std::allocatorchar
::_Rep::_M_destroy(std::allocatorchar const)'
 [...]

After scanning over the error messages, I think it's only operator,
delete and std::* symbols that are missing. I also get the same error
messages when I try to compile an equivalent C program that uses the
llvm-c/* headers with gcc, but it works with g++, so I'm quite sure the
problem is the missing c++ runtime, which is nonexistent in ldc.

I think there are only two ways to solve this:

(1) link the c++ runtime to ldc (I have no clue how to do that or if 
it's possible)
(2) Write a D library using the llvm D-bindings, define a semi-main
function as extern(C), and write a c++ wrapper program that links
to the D library and does nothing more than calling the semi-main
function. The llvm symbols and c++ runtime will then be linked in
using g++.

Option (2) seems easy, but ldc does not seem to have a linker swith to
build libraries, and doing

ldc -c myprog.d # produces myprog.o
ar -cq myprog.a myprog.o

to generate a library from the object file doesn't work because there
are still undefined symbols to the main function or the module ctors
in there, even when myprog.d doesn't define a main function. I could
try to hack those missing functions back in by defining them in the C
program, but there must be some simpler way to generate libraries,
or am I at a loosing front here?

I also consider using other compilers than ldc as an option, but afaik
the only other usable compiler might be gdc (is that stable by now?).


Re: Initialisation of static immutable arrays

2010-10-06 Thread Lars T. Kyllingstad
On Wed, 06 Oct 2010 07:39:48 -0400, Steven Schveighoffer wrote:

 On Wed, 06 Oct 2010 06:16:45 -0400, Lars T. Kyllingstad
 pub...@kyllingen.nospamnet wrote:
 
 [...]
 
 Secondly, if the above is not true, how can I verify that the array in
 the following piece of code isn't allocated and/or copied anew every
 time the program runs, or even worse, every time foo() is called?

   void foo()
   {
   static immutable int[3] = [1, 2, 3];
   }
 
 Actually, static probably will prevent it from being created every time
 foo is called.  I don't think there's a way to prevent it from being
 created every time the program is run.

Does anyone know a way to verify this?  (If it is in fact created every 
time the function runs, I'll change it to a module-level array 
initialised in a 'static this()' instead.)


 I know, RTFAsm, but some help with that would be appreciated. ;)

 Thirdly, intuition tells me that when the array is immutable, the
 'static' shouldn't have an effect.  But experiments (i.e. printing the
 adress of the array) indicate that it does.  Is there some reason for
 this, or is it just a shortcoming of the compiler?
 
 Of course.  If you realize that the expression [1,2,3] is not immutable,
 then it makes sense.
 
 Another example to help you think about it:
 
 void foo(int x)
 {
 immutable int[3] = [1,2,x];
 }
 
 This must be run on every call of foo, because x can vary.

I don't think that is a very good reason.  The compiler could detect the 
special (and, might I add, common) case where an array literal whose 
contents are known at compile time is assigned to an immutable variable, 
and treat it as immutable even though [1,2,3] is formally of type int[].


 BTW, I'm all for making array literals immutable.  You can always make
 runtime-allocated arrays via a library function.

I completely agree.

-Lars


Re: Initialisation of static immutable arrays

2010-10-06 Thread Denis Koroskin
On Wed, 06 Oct 2010 16:21:08 +0400, Lars T. Kyllingstad  
pub...@kyllingen.nospamnet wrote:



On Wed, 06 Oct 2010 07:39:48 -0400, Steven Schveighoffer wrote:


On Wed, 06 Oct 2010 06:16:45 -0400, Lars T. Kyllingstad
pub...@kyllingen.nospamnet wrote:

[...]


Secondly, if the above is not true, how can I verify that the array in
the following piece of code isn't allocated and/or copied anew every
time the program runs, or even worse, every time foo() is called?

  void foo()
  {
  static immutable int[3] = [1, 2, 3];
  }


Actually, static probably will prevent it from being created every time
foo is called.  I don't think there's a way to prevent it from being
created every time the program is run.


Does anyone know a way to verify this?  (If it is in fact created every
time the function runs, I'll change it to a module-level array
initialised in a 'static this()' instead.)



It's static so it allocates only once. But the following:

immutable int[3] = [1, 2, 3];

always allocates, but I see no reason why it should.


Re: Using the llvm D-bindings

2010-10-06 Thread Denis Koroskin

On Wed, 06 Oct 2010 16:20:41 +0400, Manuel König manuel...@gmx.net wrote:


Hi,

did anyone have success using the llvm-2.7 D-bindings from the bindings
project http://www.dsource.org/projects/bindings on x86_64 linux? I
tried so far with ldc, but the compiler chokes about a mere 3570 lines
of unresolved symbols when linking with ldc, compiling works fine.

Short version:
==

I think the question boils down to How do I create a D library and
link it into a c++ program on x86_64 linux using ldc (or gdc or
any_other_D_compiler).

Long version:
=
Here's a snip of the linker error messages I get from ldc:

// -- file main.d
import llvm.c.Core;

void main()
{
auto context = LLVMGetGlobalContext();
}
// --

$ ldc -I=/path/to/llvm-2.7 \
-L=/usr/local/lib/libLLVM{Core,Support,System}.a main.d
/usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMContextCreate':
Core.cpp:(.text+0x57): undefined reference to `operator new(unsigned
long)'
/usr/local/lib/libLLVMCore.a(Core.o): In function
`LLVMModuleCreateWithName':
Core.cpp:(.text+0x13a): undefined reference to `operator new(unsigned
long)'
/usr/local/lib/libLLVMCore.a(Core.o): In function
`LLVMModuleCreateWithNameInContext':
Core.cpp:(.text+0x195): undefined reference to `operator new(unsigned
long)'
/usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMSetDataLayout':
Core.cpp:(.text+0x240): undefined reference to `std::basic_stringchar,
std::char_traitschar, std::allocatorchar ::basic_string(char
const*, unsigned long, std::allocatorchar const)'
Core.cpp:(.text+0x24f): undefined reference to `std::basic_stringchar,
std::char_traitschar, std::allocatorchar

::assign(std::basic_stringchar, std::char_traitschar,
std::allocatorchar  const)'

Core.cpp:(.text+0x25e): undefined reference to `std::basic_stringchar,
std::char_traitschar, std::allocatorchar

::_Rep::_S_empty_rep_storage'

Core.cpp:(.text+0x294): undefined reference to `std::basic_stringchar,
std::char_traitschar, std::allocatorchar

::_Rep::_M_destroy(std::allocatorchar const)'
[...]


After scanning over the error messages, I think it's only operator,
delete and std::* symbols that are missing. I also get the same error
messages when I try to compile an equivalent C program that uses the
llvm-c/* headers with gcc, but it works with g++, so I'm quite sure the
problem is the missing c++ runtime, which is nonexistent in ldc.

I think there are only two ways to solve this:

(1) link the c++ runtime to ldc (I have no clue how to do that or if
it's possible)
(2) Write a D library using the llvm D-bindings, define a semi-main
function as extern(C), and write a c++ wrapper program that links
to the D library and does nothing more than calling the semi-main
function. The llvm symbols and c++ runtime will then be linked in
using g++.

Option (2) seems easy, but ldc does not seem to have a linker swith to
build libraries, and doing

ldc -c myprog.d # produces myprog.o
ar -cq myprog.a myprog.o

to generate a library from the object file doesn't work because there
are still undefined symbols to the main function or the module ctors
in there, even when myprog.d doesn't define a main function. I could
try to hack those missing functions back in by defining them in the C
program, but there must be some simpler way to generate libraries,
or am I at a loosing front here?

I also consider using other compilers than ldc as an option, but afaik
the only other usable compiler might be gdc (is that stable by now?).


You should probably ask LDC guys (irc://irc.freenode.net/ldc)


Re: Initialisation of static immutable arrays

2010-10-06 Thread Steven Schveighoffer
On Wed, 06 Oct 2010 08:21:08 -0400, Lars T. Kyllingstad  
pub...@kyllingen.nospamnet wrote:



On Wed, 06 Oct 2010 07:39:48 -0400, Steven Schveighoffer wrote:

Of course.  If you realize that the expression [1,2,3] is not immutable,
then it makes sense.

Another example to help you think about it:

void foo(int x)
{
immutable int[3] = [1,2,x];
}

This must be run on every call of foo, because x can vary.


I don't think that is a very good reason.  The compiler could detect the
special (and, might I add, common) case where an array literal whose
contents are known at compile time is assigned to an immutable variable,
and treat it as immutable even though [1,2,3] is formally of type int[].


I'm not saying it is a good explanation, but it is why the compiler does  
it.  Any time an array literal occurs anywhere is an allocation.  I have  
never seen a case where the compiler optimizes that out.  Given that  
context, the behavior makes sense.


I don't think any allocation should occur here, even if array literals are  
not made immutable, because that allocation is going to be thrown away  
immediately.  I agree this should be special-cased.  I believe there are  
several bugs on array literals and allocations.


-Steve


Re: Using the llvm D-bindings

2010-10-06 Thread Manuel König
Am Wed, 06 Oct 2010 16:27:11 +0400
schrieb Denis Koroskin 2kor...@gmail.com:

 On Wed, 06 Oct 2010 16:20:41 +0400, Manuel König manuel...@gmx.net
 wrote:
 
  Hi,
 
  did anyone have success using the llvm-2.7 D-bindings from the
  bindings project http://www.dsource.org/projects/bindings on x86_64
  linux? I tried so far with ldc, but the compiler chokes about a
  mere 3570 lines of unresolved symbols when linking with ldc,
  compiling works fine.
 
  Short version:
  ==
 
  I think the question boils down to How do I create a D library and
  link it into a c++ program on x86_64 linux using ldc (or gdc or
  any_other_D_compiler).
 
  Long version:
  =
  Here's a snip of the linker error messages I get from ldc:
 
  // -- file main.d
  import llvm.c.Core;
 
  void main()
  {
  auto context = LLVMGetGlobalContext();
  }
  // --
 
  $ ldc -I=/path/to/llvm-2.7 \
  -L=/usr/local/lib/libLLVM{Core,Support,System}.a main.d
  /usr/local/lib/libLLVMCore.a(Core.o): In function
  `LLVMContextCreate': Core.cpp:(.text+0x57): undefined reference to
  `operator new(unsigned long)'
  /usr/local/lib/libLLVMCore.a(Core.o): In function
  `LLVMModuleCreateWithName':
  Core.cpp:(.text+0x13a): undefined reference to `operator
  new(unsigned long)'
  /usr/local/lib/libLLVMCore.a(Core.o): In function
  `LLVMModuleCreateWithNameInContext':
  Core.cpp:(.text+0x195): undefined reference to `operator
  new(unsigned long)'
  /usr/local/lib/libLLVMCore.a(Core.o): In function
  `LLVMSetDataLayout': Core.cpp:(.text+0x240): undefined reference to
  `std::basic_stringchar, std::char_traitschar,
  std::allocatorchar ::basic_string(char const*, unsigned long,
  std::allocatorchar const)' Core.cpp:(.text+0x24f): undefined
  reference to `std::basic_stringchar, std::char_traitschar,
  std::allocatorchar
  ::assign(std::basic_stringchar, std::char_traitschar,
  std::allocatorchar  const)'
  Core.cpp:(.text+0x25e): undefined reference to
  `std::basic_stringchar, std::char_traitschar,
  std::allocatorchar
  ::_Rep::_S_empty_rep_storage'
  Core.cpp:(.text+0x294): undefined reference to
  `std::basic_stringchar, std::char_traitschar,
  std::allocatorchar
  ::_Rep::_M_destroy(std::allocatorchar const)'
  [...]
 
  After scanning over the error messages, I think it's only operator,
  delete and std::* symbols that are missing. I also get the same
  error messages when I try to compile an equivalent C program that
  uses the llvm-c/* headers with gcc, but it works with g++, so I'm
  quite sure the problem is the missing c++ runtime, which is
  nonexistent in ldc.
 
  I think there are only two ways to solve this:
 
  (1) link the c++ runtime to ldc (I have no clue how to do that or if
  it's possible)
  (2) Write a D library using the llvm D-bindings, define a semi-main
  function as extern(C), and write a c++ wrapper program that
  links to the D library and does nothing more than calling the
  semi-main function. The llvm symbols and c++ runtime will then be
  linked in using g++.
 
  Option (2) seems easy, but ldc does not seem to have a linker swith
  to build libraries, and doing
 
  ldc -c myprog.d # produces myprog.o
  ar -cq myprog.a myprog.o
 
  to generate a library from the object file doesn't work because
  there are still undefined symbols to the main function or the
  module ctors in there, even when myprog.d doesn't define a main
  function. I could try to hack those missing functions back in by
  defining them in the C program, but there must be some simpler way
  to generate libraries, or am I at a loosing front here?
 
  I also consider using other compilers than ldc as an option, but
  afaik the only other usable compiler might be gdc (is that stable
  by now?).
 
 You should probably ask LDC guys (irc://irc.freenode.net/ldc)

Thanks, I'll try. But I think the development of LDC was put on hold
due to lack of time and interest, let's see if I can find someone
there :)



Re: Using the llvm D-bindings [solved]

2010-10-06 Thread Manuel König
Am Wed, 6 Oct 2010 14:36:16 +0200
schrieb Manuel König manuel...@gmx.net:

  
  You should probably ask LDC guys (irc://irc.freenode.net/ldc)
 
 Thanks, I'll try. But I think the development of LDC was put on hold
 due to lack of time and interest, let's see if I can find someone
 there :)
 

Well, the channel was actually full of people, and the problem was
solved quickly. Actually the solution was method (1), linking in the
stdc++ lib. For the record, here are some usage instructions for the
llvm bindings. I will commit them to the repositority later, but I'll
wait a bit and see if you have something to add.

Initial setup:
==

(1) checkout from svn
(2) cd /path/to/llvm-2.7
(3) run prebuild.sh, this builds Target.o and Ext.o which have
to be passed to the linker. For convenience, these *.o files
are also merged into a single library libllvm-c-ext.a.

Note: Target.o and Ext.o are usually not needed for the regular llvm c
interface. But the D bindings add some extra bindings, because the
official c interface just doesn't expose all functionality from the c++
interface. These are implemented as a c++ to c to d bridge (c++ to c
is Target.cpp and Ext.cpp, c to d is Target.d and Ext.d).

Building your application:
==

To compile and link a file main.d, run

LLVMD=/path/to/llvm-dbindings
LLVM_LIBS=`llvm-config --libs | sed 's/-l/-L-l'`
ldc -I=$LLVMD \
-L=$LLVMD/{Target,Ext}.o \
$LLVM_LIBS \
-L-ldl -L-lstdc++ -relocation-model=pic \
main.d

Parameters:
LLVM_LIBS a list of all llvm libraries, formatted for
ldc -L=$LLVMD/{Target,Ext}.o  only needed when you use Target.d or Ext.d
-L-lstdc++links in the c++ standard library (llvm at
it's core is c++) -relocation-model=pic necessary for calling code
in your app from inside of the llvm vm



Re: Using the llvm D-bindings [solved]

2010-10-06 Thread Manuel König
The previous Initial setup description didn't pass the copy paste
test, now it's more instructive. The same should work for llvm 2.6 and
2.8, too (yes, 2.8 was just released and the bindings are already
there :)

Initial setup:
==

svn co http://svn.dsource.org/projects/bindings/trunk/llvm-2.7
cd llvm-2.7
./prebuild.sh

prebuild.sh builds Target.o and Ext.o which have to be passed
to the linker. For convenience, these *.o files are also merged
into a single library libllvm-c-ext.a.

Target.o and Ext.o are usually not needed for the regular
llvm c interface. But the D bindings add some extra bindings,
because the official c interface just doesn't expose all
functionality from the c++ interface. These are implemented as a
c++ to c to d bridge (c++ to c is Target.cpp and Ext.cpp, c to
d is Target.d and Ext.d).

Building your application:
==

To compile and link a file main.d, run

LLVMD=/path/to/llvm-dbindings
LLVM_LIBS=`llvm-config --libs | sed 's/-l/-L-l'`
ldc -I=$LLVMD \
$LLVM_LIBS \
-L=$LLVMD/libllvm-c-ext.a \
-L-ldl -L-lstdc++ -relocation-model=pic \
main.d 

Parameters:
LLVM_LIBS a list of all llvm libraries, formatted for
ldc -L=$LLVMD/libllvm-c-ext.a only needed when you use Target.d or Ext.d
-L-lstdc++links in the c++ standard library (llvm at
it's core is c++) -relocation-model=pic necessary for calling code
in your app from inside of the llvm vm


Re: Using the llvm D-bindings [solved]

2010-10-06 Thread mwarning
On Wed, 06 Oct 2010 16:57:09 +0200, Manuel König wrote:

 LLVM_LIBS=`llvm-config --libs | sed 's/-l/-L-l'`

typo detected, you need:
sed 's/-l/-L-l/g'

:)


write to file ... trivial?

2010-10-06 Thread Dr. Smith
This should be trivial.  However, I've not found in the documentation (trying
both std.stdio and std.file) how to write to a file in the manner here:

filename.writefln(%s\t%f, someString, someDouble);

... this merely prints filename to screen ... does not create a data file.


Re: write to file ... trivial?

2010-10-06 Thread Denis Koroskin

On Wed, 06 Oct 2010 22:43:42 +0400, Dr. Smith i...@far.out wrote:

This should be trivial.  However, I've not found in the documentation  
(trying

both std.stdio and std.file) how to write to a file in the manner here:

filename.writefln(%s\t%f, someString, someDouble);

... this merely prints filename to screen ... does not create a data  
file.


In your case, foo.bar(args) == bar(foo, args) - that is call Uniform  
Function Call Syntax, that is:


filename.writefln(%s\t%f, someString, someDouble); - writefln(filename,  
%s\t%f, someString, someDouble);


which in turn tries using filename as a format.

Try using std.stream. It should be something like this:

File file = new File(fileName, FileMode.OutNew); // open file for writing,  
create new if none exists

file.writefln(hello, %s!, world);

Not tested but should work.


Re: write to file ... trivial?

2010-10-06 Thread Seth Hoenig
Here's a minimal little template (checked):

import std.stdio;

void main()
{
auto f = File(outfile.txt, w);
f.writefln(%s World, Hello);
f.close();
}





2010/10/6 Denis Koroskin 2kor...@gmail.com

 On Wed, 06 Oct 2010 22:43:42 +0400, Dr. Smith i...@far.out wrote:

  This should be trivial.  However, I've not found in the documentation
 (trying
 both std.stdio and std.file) how to write to a file in the manner here:

 filename.writefln(%s\t%f, someString, someDouble);

 ... this merely prints filename to screen ... does not create a data file.


 In your case, foo.bar(args) == bar(foo, args) - that is call Uniform
 Function Call Syntax, that is:

 filename.writefln(%s\t%f, someString, someDouble); - writefln(filename,
 %s\t%f, someString, someDouble);

 which in turn tries using filename as a format.

 Try using std.stream. It should be something like this:

 File file = new File(fileName, FileMode.OutNew); // open file for writing,
 create new if none exists
 file.writefln(hello, %s!, world);

 Not tested but should work.



Re: write to file ... trivial?

2010-10-06 Thread Dr. Smith
Thank you.  Indeed, I forgot: auto f = File(outfile.txt, w);

Interestingly, this apparently works within a for-loop to overwrite the file on
the first iteration and appending otherwise (Should there not be an explicit
append arg?):

for(int i = 0; i  100; i++) {
  f.writefln(%s%i, World Hello, i);
} f.close(); // f.close outside the loop for efficiency?

If someone could point me to the online documentation for this matter, I'd
appreciate it.  I'd prefer to use this forum for less elementary matters.


Re: write to file ... trivial?

2010-10-06 Thread Jesse Phillips
Dr. Smith Wrote:

 Thank you.  Indeed, I forgot: auto f = File(outfile.txt, w);
 
 Interestingly, this apparently works within a for-loop to overwrite the file 
 on
 the first iteration and appending otherwise (Should there not be an explicit
 append arg?):
 
 for(int i = 0; i  100; i++) {
   f.writefln(%s%i, World Hello, i);
 } f.close(); // f.close outside the loop for efficiency?
 
 If someone could point me to the online documentation for this matter, I'd
 appreciate it.  I'd prefer to use this forum for less elementary matters.

auto f = File(name, options);

Creates a new File object which, based on the options, opens the file for 
writing (create and replace), reading (binary or text), or appending. All 
operations are performed on this open file until closed and reopened. So for 
your example if you do not wish to append to an open file you can do this



Now you can get the same behavior even if you close the File with:

for(int i = 0; i  100; i++) {
auto f = File(name.txt, a);
f.writefln(%s%i, World Hello, i);
f.close(); 
}

Notice the a instead of w This is appending to the file when it opens it. 
Thus the reason the first example has f.close outside the loop is because it is 
opening the File outside the loop.

http://digitalmars.com/d/2.0/phobos/std_file.html