Re: how can I ensure that a template instantiation is unique?
On 6/19/14, 1:48 AM, Vlad Levenfeld wrote: I'm instantiating a couple of template structs that conflict with each other. I'd like them to be unique types, automatically. So I tried this: template Foo (string unique_id = __FILE__~__LINE__.to!string) {...} but it didn't work. When I use this for templated functions, I get the file and line number where the function is instantiated. But in this case, I got the file and line number where the template was defined. Is there anything I can do to make sure each instantiated type is unique? I don't think you want to set a default value. If you pass __FILE__~__LINE__.to!string during instantiation, it works every time: template Foo(string uniqueId) { alias Foo = uniqueId; } void main() { Foo!(__FILE__~__LINE__.to!string).writeln; }
Re: how can I ensure that a template instantiation is unique?
On Thursday, 19 June 2014 at 05:48:24 UTC, Vlad Levenfeld wrote: I'm instantiating a couple of template structs that conflict with each other. I'd like them to be unique types, automatically. So I tried this: template Foo (string unique_id = __FILE__~__LINE__.to!string) {...} but it didn't work. When I use this for templated functions, I get the file and line number where the function is instantiated. But in this case, I got the file and line number where the template was defined. Is there anything I can do to make sure each instantiated type is unique? Maybe something like this: http://dpaste.dzfl.pl/ce479a2f87f4
Re: how can I ensure that a template instantiation is unique?
On Thursday, 19 June 2014 at 07:26:12 UTC, Andrea Fontana wrote: On Thursday, 19 June 2014 at 05:48:24 UTC, Vlad Levenfeld wrote: I'm instantiating a couple of template structs that conflict with each other. I'd like them to be unique types, automatically. So I tried this: template Foo (string unique_id = __FILE__~__LINE__.to!string) {...} but it didn't work. When I use this for templated functions, I get the file and line number where the function is instantiated. But in this case, I got the file and line number where the template was defined. Is there anything I can do to make sure each instantiated type is unique? Maybe something like this: http://dpaste.dzfl.pl/ce479a2f87f4 Of course Foo2 could be an enum :)
Re: how can I ensure that a template instantiation is unique?
Thanks! Mixin strings can punch through anything.
Re: Placement of shared does not allow to set a delegate
Yes the understanding is correct. I simplified the code a little: IMPORTANT: DMD 2.065 is used. class Car{ void delegate() onEvent; } class Test{ this() shared { auto car = new shared Car(); assert( typeid( car.onEvent ).toString() == shared(void delegate()) ); assert( typeid( car_onEvent1 ).toString() == void delegate() ); assert( typeid( car_onEvent2 ).toString() == void delegate() ); assert( typeid( cast(shared)( car_onEvent2 ) ).toString() == shared(void delegate()) ); car.onEvent = car_onEvent1; car.onEvent = car_onEvent2; // COMPILATION ERROR car.onEvent = cast(shared)( car_onEvent2 ); // COMPILATION ERROR } void car_onEvent1(){} void car_onEvent2() shared{} } void main(){ new shared Test(); } I just want to know if I am doing a mistake, thinking in wrong way, or there is a bug. The first compilation error is that it cannot convert void delegate() shared to shared(void delegate()). The second compilation error is that it cannot convert shared(void delegate()) to shared(void delegate()). (Since DMD 2.066 is not ready yet, I need to continue with 2.065.) On Tuesday, 17 June 2014 at 04:35:10 UTC, Ali Çehreli wrote: I don't know but I theorize like this: :) There are three 'shared' qualifiers in the last error message. shared(void delegate(shared(SocketListener)) shared) 1) The 'shared' in the middle: That one makes the delegate take a shared(SocketListener) argument when it gets called. 2) The 'shared' on the right-hand side: (I am not sure about this one.) That one makes the context pointer of the delegate 'shared'. For example, the delegate can only be called on a shared class object. 3) The 'shared' on the left-hand side: That one makes the type of the delegate shared so that e.g. such a delegate can be passed between threads. That's what I understand. Ali
Re: Concurrency on Windows (spawn)
On Wednesday, 18 June 2014 at 15:23:11 UTC, Kapps wrote: On Wednesday, 18 June 2014 at 15:03:55 UTC, Ali Çehreli wrote: On 06/18/2014 06:28 AM, Chris wrote: On Wednesday, 18 June 2014 at 11:57:06 UTC, Chris wrote: Windows: in a D-DLL I'm trying to spawn a thread. However, nothing happens auto myThread = spawn(myFunction, thisTid); send(myThread, arg); The thread is never called. Any ideas? Thanks! PS In an old DLL it used to work, there I called it with only one argument, i.e. spawn(myFunction). Is thisTid messing it up, do I need to pass something else? Mystery solved. There was an audio delay so that the program had already finished, before the thread was properly executed. I _lve_ Windows! Not! That can happen on Linux as well. So, the owner may have to call thread_joinAll() to wait for the worker: import core.thread; auto myThread = spawn(myFunction, thisTid); send(myThread, arg); // ... sometime before the program ends: thread_joinAll(); Ali Alternatively, one should use non-daemon threads for this purpose. http://dlang.org/phobos/core_thread.html#.Thread.isDaemon Yeah, I've read about that, I think Adam mentions this in his cookbook as well. For my application the thread merely plays an audio file and is interrupted as soon as new input comes. The issue only came up, because in a test program the app finished, before Windows started to play (audio delay). In the real world app this isn't a problem cause it stays up an running. But still, I'm experiencing some weird behavior that might be down to the whole threading thing. Happy debugging!
Re: Some kind of RPC exists for D?
What I want to do is some little framework that allows Julia-style (julialang.org) distributed computation: send some function invocation to some other machine along with the numbers to be crunched and get the result back. vibe.web.rest server/client combo is effectively RPC over HTTP/json This looks good. For what am I'm thinking of doing performance is important. In that way rest makes me think a bit or is this only a prejudice from the Java world? I wrote an implementation of Thrift for D a while back This also looks interesting. Because my C/C++/D skills are limited being a Smalltalk/Java developer (only played with C++ when studying) I have to stick to what is easier to use. It would be a fun leisure learning project anyway... Regards, Bienlein
Re: How to I call D code from C# Project?
On Wednesday, 18 June 2014 at 20:55:09 UTC, GoD wrote: Hi. I want use my D code in C# How can I do this? D, very fast programming language. But I can not WinForm applications from D. I'm using C# for WinForm applications. But, also i want to use D code for my project. for example; I'm see PC information with D lang. Example Code(Suppose that D): PCInformation //D LANG CODE { showHDDSerialNumber(); showCPUsage(); showMACAdress(); showFooBar(); } Example Code(Suppose that C#): using namespace DCODE; // DCODE Library written it D Lang WinFormApp { PCInformation pin = new PCInformation(); // D code import Label1.Text = pin.ShowHDDSerialNumber(); // D code import } How can I do this? Sorry for my bad english :( Thank you :) You could write a DLL un D, and call that from C# with PInvoke. http://wiki.dlang.org/Win32_DLLs_in_D http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx
Re: Working on a library: request for code review
On Wednesday, 18 June 2014 at 14:05:12 UTC, Rene Zwanenburg wrote: On Tuesday, 17 June 2014 at 13:07:33 UTC, Marc Schütz wrote: On Monday, 16 June 2014 at 23:04:33 UTC, Rene Zwanenburg wrote: This one depends on taste, but these helpers can be eliminated by changing the Header definition a little. It's the same union / anonymous struct trick from the previous post, only this time with bitfields: http://dpaste.dzfl.pl/13258b0ce0c4 If you define nested structs/unions, it's better to make them static whenever possible, because non-static nested structs have an additional hidden field for the context. Good call. In this case it doesn't add the hidden field, but for the sake of consistency I agree it's better to add static. Interesting, I thought it's there for all nested structs. But I see it's only added if the struct has a method, but then it's always there, no matter whether the methods actually accesses the outer context. Probably for consistency reasons...
Re: Some kind of RPC exists for D?
On Thursday, 19 June 2014 at 10:25:08 UTC, Bienlein wrote: vibe.web.rest server/client combo is effectively RPC over HTTP/json This looks good. For what am I'm thinking of doing performance is important. In that way rest makes me think a bit or is this only a prejudice from the Java world? It is not very suitable for applications where response latency is important because HTTP itself and JSON (de)serialization create considerable needless overhead (compared to something like thrift). However if you application design implies thousands of RPC calls per second it is quite likely performance won't be good with any RPC implementation :)
DUB linking problem on WinXp
I've this dub.json { name: ega_editor, description: Editor for ega database, targetType: executable, targetPath: bin, dependencies: { sdlang-d: =0.8.4, ddb: =0.2.1, dejector: ~master, gtk-d:gtkd: =2.3.3 } } and under linux it works well. Under WinXp I got the following Linking... dmd -of.dub\build\application-debug-windows-x86-dmd-78940A919140142F73EC858336385DF4\ega_editor.exe .dub\build\application-debug-windows-x86-dmd-78940A919140142F73EC858336385DF4\ega_editor.obj C:\Documents and Settings\dao\Application Data\dub\packages\dejector-master\dejector.lib C:\Documents and Settings\dao\Application Data\dub\packages\dunit-1.0.9\dunit.lib C:\Documents and Settings\dao\Application Data\dub\packages\sdlang-d-0.8.4\sdlang-d.lib C:\Documents and Settings\dao\Application Data\dub\packages\ddb-0.2.1\ddb.lib C:\Documents and Settings\dao\Application Data\dub\packages\gtk-d-2.3.3\gtkd-2.lib -g --- errorlevel 1 FAIL .dub\build\application-debug-windows-x86-dmd-78940A919140142F73EC858336385DF4\ ega_editor executable Error executing command build: dmd failed with exit code 1 Full exception: object.Exception@source\dub\compilers\compiler.d(236): dmd failed with exit code 1 0x004CC9F2 0x00437462 0x004394BA 0x00441FFD 0x004405C1 0x00440240 0x0043FEDE 0x0043FB08 0x00443A06 0x00410549 0x00404D6C 0x00405017 0x00403538 0x00402106 0x004BCD30 0x004BCD03 0x004BCC1B 0x0040271C 0x0050A33D 0x7C816037 in CreateActCtxW My dub version is DUB version 0.9.22-beta.3, built on Jun 12 2014 Thanks a lot!
Re: DUB linking problem on WinXp
On Thursday, 19 June 2014 at 12:18:54 UTC, Orfeo wrote: Under WinXp I got the following AFAIK, D is not officially supported on Win XP. That's probably why you don't have a meaningful stacktrace or error message.
Re: Working on a library: request for code review
On Thursday, 19 June 2014 at 12:06:58 UTC, Marc Schütz wrote: On Wednesday, 18 June 2014 at 14:05:12 UTC, Rene Zwanenburg wrote: On Tuesday, 17 June 2014 at 13:07:33 UTC, Marc Schütz wrote: On Monday, 16 June 2014 at 23:04:33 UTC, Rene Zwanenburg wrote: This one depends on taste, but these helpers can be eliminated by changing the Header definition a little. It's the same union / anonymous struct trick from the previous post, only this time with bitfields: http://dpaste.dzfl.pl/13258b0ce0c4 If you define nested structs/unions, it's better to make them static whenever possible, because non-static nested structs have an additional hidden field for the context. Good call. In this case it doesn't add the hidden field, but for the sake of consistency I agree it's better to add static. Interesting, I thought it's there for all nested structs. But I see it's only added if the struct has a method, but then it's always there, no matter whether the methods actually accesses the outer context. Probably for consistency reasons... The absence of the hidden field without methods is probably to maintain C compitability; code that is both valid C and D must have the same semantics. I think that includes struct layout?
Link to C library
I can't link to libjvm.so. Here's my code: extern (C) { int JNI_CreateJavaVM(void ** pvm, void ** penv, void * args); } void main() { writefln(0x%x, .JNI_CreateJavaVM); } Which ptints wrong stuff. When then i use it and check the contents of **pvm is also prints wrong stuff full of zeroes, but the result is 0(JNI_OK). I build it with: dmd -m64 main.d -I. -L-ljvm -debug. Any suggestions?
rehabilitating Juno
This is specifically for Jesse K Phillips, Jesse, It appears we're both interested in Juno. You lack time and I lack D experience. What could a D clown do for your juno repository to get it functional again. The last time I grabbed the code and ran it vs. current D compiler I got a whole bunch of errors for what appear to be base D packages. Feel free to give me scutwork if that will help get Juno back into orbit.
Re: Link to C library
Oh, found a problem, it was about one more layer of pointer indirection.
Re: DUB linking problem on WinXp
Thank you for your reply... On Thursday, 19 June 2014 at 12:28:31 UTC, Mathias Lang wrote: 8 AFAIK, D is not officially supported on Win XP. 8 The strange thing is that it worked yesterday and not today. I have also tried with Win7 64bit (on Virtual Box) and the problem it's the same...
Re: How to I call D code from C# Project?
On Wednesday, 18 June 2014 at 20:55:09 UTC, GoD wrote: D, very fast programming language. But I can not WinForm applications from D. I'm using C# for WinForm applications. DWT and TkD didn't work for you?
Re: How to I call D code from C# Project?
I know it but I can not do without the drag-and-drop. (Design etc..)
Re: Some kind of RPC exists for D?
On Thursday, 19 June 2014 at 13:54:01 UTC, David Nadlinger wrote: On Thursday, 19 June 2014 at 12:13:12 UTC, Dicebot wrote: However if you application design implies thousands of RPC calls per second it is quite likely performance won't be good with any RPC implementation :) Backend people at Google, Facebook, and others would beg to disagree. ;) Of course, the calls counted here are from multiple clients to a single server. If your fan-out is in the thousands, then you indeed have a problem. David Yes, you are correct, I have indeed meant bi-direction distributed communication model, something similar to what Erlang provides out of the box. Of course in classical client-server model handling even tens of thousands of RPC calls per second is feasible.
Re: DUB linking problem on WinXp
The problem was on ddb 0.2.1 ... if I remove it I can compile
Re: rehabilitating Juno
On Thursday, 19 June 2014 at 13:06:15 UTC, Jason King wrote: This is specifically for Jesse K Phillips, Jesse, It appears we're both interested in Juno. You lack time and I lack D experience. What could a D clown do for your juno repository to get it functional again. The last time I grabbed the code and ran it vs. current D compiler I got a whole bunch of errors for what appear to be base D packages. Feel free to give me scutwork if that will help get Juno back into orbit. I should be able to bring the repository up to latest dmd compiler (I'll see what I can do this weekend). If I recall the situation was that utilizing COM was working, a COM service could be created but I couldn't get the security cert to work. I believe I had it compiling under 64bit but couldn't run any of the examples. Once I get some examples compiling again in 32bit, it should be easier for you to play around with COM in D.
Re: Run child process with null stdin/stdout
On Wed, 18 Jun 2014 16:15:40 -0400, David Nadlinger c...@klickverbot.at wrote: On Wednesday, 18 June 2014 at 20:00:43 UTC, Justin Whear wrote: For POSIX, seems like you could pass `File(/dev/null, r)` for stdin and `File(/dev/null, w)`. On Windows I believe you can use `File (nul)` for the same effect. Implementing this myself is of course always an option, yes, but I would have liked to avoid platform-dependent code. Hm, I just checked the source, and there doesn't seem to be a better option indeed… I think a mechanism to open a null stream in an OS independent way would be a good addition to std.stdio (or perhaps std.process?) -Steve
Tango Server Example
reference: Tango Server: http://www.dsource.org/projects/tango/wiki/SocketServerExample Tango Client: http://www.dsource.org/projects/tango/wiki/SocketHelloExample I'm referring to these two examples. In the server Example, I strip off the client part and it becomes as follow. void main() { const int port = 8080; // thread body for socket-listener void run() { auto server = new ServerSocket (new IPv4Address(port)); // wait for requests auto request = server.accept; // write a response request.output.write (server replies 'hello'); } Cout(server started); while (true ) { // start server in a separate thread, and wait for it to start (new Thread (run)).start; tango.core.Thread.thread_sleep (0.250); } } Situation: I have my server running and I open a client in another cmd console window and it replied alright. But if I try to connect it again second time, it freezes. Why is that? I thought the server is constantly receiving messages and replying, why would it freeze up and stop responding? what went wrong? please advise. Thanks
Re: DUB linking problem on WinXp
On Thursday, 19 June 2014 at 15:12:10 UTC, Orfeo wrote: The problem was on ddb 0.2.1 ... if I remove it I can compile Did you try a full rebuild? dub --force sometimes helps, especially when you've upgraded your compiler.
Re: Tango Server Example
I modify the server program as follow and it works ok. But how do I use thread to expedite the execution? void main() { const int port = 8080; auto server = new ServerSocket (new IPv4Address(port)); Cout(server started); while (true ) { // wait for requests auto request = server.accept; // write a response request.output.write (server replies 'hello'); request.close; } }
Re: Working on a library: request for code review
Once again thanks for the feedback. The RLE rewrite using std is impressive! I will use it today or tomorrow, great stuff.
Re: DMD Fails with fPIC error
On 06/18/2014 08:51 AM, Reuben wrote: On Sunday, 15 June 2014 at 09:08:10 UTC, Mike Wey wrote: In that case the static Phobos needs to be build with -fPIC, which currently isn't the case looking at the Ebuild. Compiling DMD with PIC=1 doesn't seem to do the trick. -fPIC is used for the C files, but when linking Phobos the following appears: /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: generated/linux/release/64/libphobos2.so.0..o: warning: relocation in readonly section `.deh_eh'. /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object. Compiling dmd with -fPIC shoudn't matter, building the static version of Phobos works for me (make -f posix.mak DFLAGS=-fPIC), but i don't have an hardened gcc, so that may be why. Google tells me the DT_TEXTREL error is because of non -fPIC objects in a shared library. Compiling with it then gives the following: $ ./dmd test.d ... error ... readelf doesn't show any TEXTRELs in libc, so I assume it is also hardened. test.d still needs to be build with -fPIC. -- Mike Wey
dub --annotate option
Dub has option called --annotate. It's described like this: Do not perform any action, just print what would be done I supposed it's something similar to -n option of Jam build system (I really like this feature). But dub's annotate prints nothing. So what is that? I have DUB version 0.9.21
Re: Some kind of RPC exists for D?
On Wednesday, 18 June 2014 at 19:24:03 UTC, Bienlein wrote: Hello, I'm looking for a way to do some kind of RPC in D. Some way of being able to say aFoo.bar(int i, ...) with receiver object and method being marshalled at the sender's site and being unmarshalled and invoked at the receiver's site. Any hints appreciated. Thanks, Bienlein What data load profile do you expect? Vibe is tuned to handle thousands simultaneous incoming light requests (milliseconds), while distributed computing works better with exclusive heavy requests, at least minutes of work worth, BOINC uses hours worth work items.
Re: dub --annotate option
On Thursday, 19 June 2014 at 17:45:56 UTC, FreeSlave wrote: Dub has option called --annotate. It's described like this: Do not perform any action, just print what would be done I supposed it's something similar to -n option of Jam build system (I really like this feature). But dub's annotate prints nothing. So what is that? I have DUB version 0.9.21 I would raise an issue here: https://github.com/D-Programming-Language/dub/issues Sönke is very prompt at replying to issues. :)
Re: Tango Server Example
I solved it. void main() { const int port = 8080; auto server = new ServerSocket (new IPv4Address(port)); Cout(server started).flush; while (true ) { // wait for requests auto request = server.accept; // write a response // // start server in a separate thread, and wait for it to start (new Thread ( { // do lots of things here or add some functions for processing request.output.write (server replies 'hello'); request.close; })).start; } }
how to store a range transformed by a range function?
I've got an app that uses a custom range type over some preallocated arrays. These arrays are accessed through a getter fuction (supplied by the struct that is maintaining a unique reference to the array) that returns a T[]. Typical usage involves a source range, target range, and a graph of maps, filters, zip and reductions piping data from the source to the target. It is the fastest range-based processing scheme I could think of (I say because it avoids the GC as far as I know). I would like if I had the option to not care exactly where the actual data is coming from (or going to) during computation. I'd like to be able to take a node in the computational graph and store it so that when I access it later, it pulls data from some managed array (or perhaps a transformed range from another saved node) and returns the transformed range. For example, lets say I had a couple of managed arrays of doubles, and I had some computational path that, at some point, took these two ranges and zipped them before passing them along. At that node (where the zip is performed) I'd like to save a struct that, upon request, returns a Tuple!(double, double) range populated with the current values of the source double[]s. Then anything which uses that struct is only exposed to a range of ordered pairs, which fell from the sky as far as anything on the client-side of the interface is concerned. Of course I can't, not right off the bat, because storage requires specifying a type to store, and the actual type of a lazy-evaluated functional result depends on how it was constructed (Voldemort types as I've heard them called), so there's no way to, say, keep an array of these (unless they all have the same source types and underwent the same transformations). So even if I could create such a midway node struct, I wouldn't have any feasible way to store a set of them. The only workable idea I've had so far is to basically ape the Result structs from std.algorithm, replacing the aliased function with a function pointer. The pointer will be more costly than the alias, but it would be storable (and smaller and easier to manage than a whole bunch of temporary buffers). I was hoping to get some opinion on options and alternatives for this situation from some experienced D coders. Maybe needing something like this to begin with is a code smell?
Re: how to store a range transformed by a range function?
On Thu, Jun 19, 2014 at 08:02:39PM +, Vlad Levenfeld via Digitalmars-d-learn wrote: [...] For example, lets say I had a couple of managed arrays of doubles, and I had some computational path that, at some point, took these two ranges and zipped them before passing them along. At that node (where the zip is performed) I'd like to save a struct that, upon request, returns a Tuple!(double, double) range populated with the current values of the source double[]s. Then anything which uses that struct is only exposed to a range of ordered pairs, which fell from the sky as far as anything on the client-side of the interface is concerned. Of course I can't, not right off the bat, because storage requires specifying a type to store, and the actual type of a lazy-evaluated functional result depends on how it was constructed (Voldemort types as I've heard them called), so there's no way to, say, keep an array of these (unless they all have the same source types and underwent the same transformations). So even if I could create such a midway node struct, I wouldn't have any feasible way to store a set of them. I've run into this before. The solution is to use a class-based wrapper from std.range to wrap around the range and expose a uniform external type: // Original version (doesn't compile): auto func(R)(R inputRange) { if (someCondition) return inputRange.map!((x)=x+1); else return inputRange.filter!((x) = x 10); // Compile error: map() and filter() don't return the // same type, so the return type of func() cannot be // determined! } // Solution: import std.range : inputRangeObject; InputRange!E func(R,E)(R inputRange) { if (someCondition) return inputRangeObject(inputRange.map!((x)=x+1)); // N.B. the object returned by inputRangeObject // implements the InputRange!E interface. else return inputRangeObject(inputRange .filter!((x) = x 10)); // N.B.: this object also implements the same // InputRange!E interface. // Since both branches implement the InputRange!E // interface, we can use that as the uniform external // type to represent either returned range. } This example, of course, illustrates the functional solution to the problem; in your case, you can just store the InputRange!E interfaces in your nodes, and you can assign different kinds of ranges to it, as long as they have a common element type. Exactly which concrete type is behind the InputRange!E interface reference can be determined at runtime; it doesn't have to be known at compile-time. T -- We are in class, we are supposed to be learning, we have a teacher... Is it too much that I expect him to teach me??? -- RL
Re: how to store a range transformed by a range function?
Thank you. This would work, however I'm wary of a class-based solution. InputRangeObject.save() calls new and it appears opSlice is unimplemented for some technical reasons... I think perhaps, since my case is more specialized than the use cases InputRangeObject is meant for, wrapping some kind of functor in a struct range implementation would be equivalent to this (minus the heap allocations, plus slicing) for my purposes.
how to correctly 'typedef' handle types
import std.stdio; import core.sys.windows.windows; int main(string[] argv) { HGDIOBJ h; // Compile error: // Error 1 Error: main.foo called with argument types (void*) matches both: D:\Projetos-D\ConsoleApp1\main.d 12 // Error2 main.foo(void* h) D:\Projetos-D\ConsoleApp1\main.d17 // Error3 main.foo(void* h) D:\Projetos-D\ConsoleApp1\main.d21 foo(h); return 0; } void foo(HGDIOBJ h) { } void foo(HACCEL h) { } I want my 2 overloaded 'foo' functions to be able to differentiate when the passed parameter is a HGDIOBJ or a HACCEL...but it doesn't compile (error in the code above) The problem lies in how I am declaring those 2 types cause they are aliases for the same base type: 'void*' dont't know how to solve it! thks for helping