April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | On Wednesday, 30 April 2014 at 14:18:37 UTC, Ary Borenszweig wrote:
> When I have a bug in my code I usually add a test for it so it never happens again.
>
> Because it's a bug, I might need to debug it. So I add a couple of "writefln" instead of using a debugger (it's faster and I get formatted results easier).
>
> Now, if I run all tests I will get output from all the tests, not the one I'm trying to debug. That's really annoying.
Output from the failing test will always be the last one in console. Pipe to tail -> profit. This sounds as pure aesthetics issue.
|
April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Wed, Apr 30, 2014 at 02:25:05PM +0000, Dicebot via Digitalmars-d wrote: > On Wednesday, 30 April 2014 at 14:18:37 UTC, Ary Borenszweig wrote: > >When I have a bug in my code I usually add a test for it so it never happens again. > > > >Because it's a bug, I might need to debug it. So I add a couple of "writefln" instead of using a debugger (it's faster and I get formatted results easier). > > > >Now, if I run all tests I will get output from all the tests, not the one I'm trying to debug. That's really annoying. > > Output from the failing test will always be the last one in console. Pipe to tail -> profit. This sounds as pure aesthetics issue. What I usually do is to be writefln at the start and end of the failing test, so I know exactly which part of the output belongs to the failure: unittest { writeln("Starting failing test"); ... // stuff writeln("debug value = %s", ...); ... // stuff writeln("End failing test"); } Then just pipe it to: sed -ne/^Starting\ failing\ test/,/^End\ failing\ test/p and you're good to go. :-) (The "End" message is there so that you're sure the failure is coming from this test, not somewhere else, and also serves as an indicator of when the problem gets fixed and it moves on to the next test.) T -- It's amazing how careful choice of punctuation can leave you hanging: |
April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On Wednesday, 30 April 2014 at 09:22:06 UTC, Chris wrote: > Is there any documentation for web.d, including example apps? Not much, I've done some before but it is pretty scattered and I don't even know where it all is right now. > I basically implemented the most important JS features for DOM manipulation and added stuff I'd always wanted in JS. Yeah, dom.d is kinda my magical group of nice convenience too. The .addChild() helper makes building a tree in code so simple that I rarely even thing about innerHTML anymore. addChild takes a tag name and two child strings which are customized based on the tag name: addChild("a", "Link test", "http://link-target.com/"); // makes <a href="httpp....">Link test</a> addChild("span", "foo", "bar"); // makes <span class="bar">foo</span> addChild("div", Html("<b>lol</b>")); // <div><b>lol</b></div> (normally, the second argument is innerText and the third argument is the big customization point.) dom.d's Form class makes them stupid-simple to use too. auto form = document.requireSelector!Form("#my-form"); form.setValue("something", "else"); setValue finds the element with that particular name and sets teh value based on what it is. So if it is an <input>, it sets value. If it is a <textarea>, it sets innerText. If it is <select>, it sets the attribute on the right <option>, or can add an option if needed. It can also implicitly create a hidden element if needed. The Link class has a similar function for link URL params. And, of course, these can be done in a loop: void forwardParams() { foreach(k, v; cgi.post) form.setValue(k, v); } so simple! |
April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | > A JIT for D? That would be many, many man-years of work.
Wrong!
It would be quite easy. I've figured it out myself.
I've thought of using Pegged with PEG/BNF ParseTrees, made faster using ParseTree serialization matched to the source's CRC32-encoding for memoization, with a multi-threaded model of tree-generation when branching in Or! steps.
Then, the interpretation stage can re-create the D environment with hash maps of a "Entity" Variant of D types, functions, values and instantiations added with their respective identifiers, each as a single Entity struct containing their instructions as a simple array.
e.g. struct Entity { Entity[] scope; Entity[] instructions }
Once that's done, you should have all your types and objects in HashMaps, ready to execute with an entry point. You move through the instructions with a foreach loop by looking up function calls and expecting the appropriate return type.
Call me crazy, but I think typed variants would be easier and faster to handle than the regular casting methods that interpreted languages use currently.
Anyway, the hardest part again would be to write a good garbage collector.
|
April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | On Wednesday, 30 April 2014 at 12:26:06 UTC, Nick Sabalausky wrote: > Automatic forms generated from a type are nice for quick-n-dirty stuff, but I find they tend to work against (or at least be much less useful for) the tweaking and customization usually needed in public-facing production sites. Aye, I rarely use my automatic forms on live sites either.... but they are really nice for backend CRUD stuff or a quick-n-dirty first-draft. Sometimes though, I can get away with just modifying an automatic form and kinda want to make web.d 2.0 better at that. > Instead of defining the form in the server-side code and then awkwardly trying to make it generate the HTML I want, I just define the form in HTML. (Or rather, in an HTML template that's still more-or-less valid HTML, with a few additional non-standard tags to help with metadata like "how to validate this field"). Yes, rox rox rox. This is what my html.d originally was for btw, expanding non-standard tags. Many of them are obsolete now tho, I use html5 attributes instead. Of course, html.d also includes other cool stuff like CSS expansion and JS foreach macros too, as we fairly recently talked about. > Then I use Adam's dom.d (in non-strict mode) to read the HTML form template (preserving the templating stuff) I use strict mode for that stuff, keep in mind strict mode is about well-formedness, not validation. So it accepts custom tags and attributes easily enough. |
April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | On Wednesday, 30 April 2014 at 13:47:11 UTC, Ola Fosheim Grøstad wrote: > You might dislike this, but I think nimble servers and clean separation with javascript heavy clients are the future. > > What I don't want: > > - I have started to avoid server processing of forms, javascript/ajax gives better user experience. I don't really agree, I do as much work as I can on the server, I like the AJAX stuff to be as stupid simple as setting innerHTML. (Indeed, web.d's automatic javascript has helper functions for this: Server.getSomeData(args).useToReplace(some_element); ) It makes it a lot simpler and gives good compatibility since the client is pretty thin. > - I avoid advanced routing, it adds little and leads to harder to maintain code, give me a regexp based routing table in one location binding request-handlers. aye, I think routing is generally ridiculous. > - Server side generation should be kept minimal, prevents caching. That's not really true. You can cache individual parts on the server and in some cases, cache the whole page on the client too. Of course, doing things on the server may not need to be cached anyway because you don't have the lag of a million http requests in putting it together. |
April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On 4/30/14, 11:25 AM, Dicebot wrote:
> On Wednesday, 30 April 2014 at 14:18:37 UTC, Ary Borenszweig wrote:
>> When I have a bug in my code I usually add a test for it so it never
>> happens again.
>>
>> Because it's a bug, I might need to debug it. So I add a couple of
>> "writefln" instead of using a debugger (it's faster and I get
>> formatted results easier).
>>
>> Now, if I run all tests I will get output from all the tests, not the
>> one I'm trying to debug. That's really annoying.
>
> Output from the failing test will always be the last one in console.
> Pipe to tail -> profit. This sounds as pure aesthetics issue.
That's good.
What if you have tests against a database that where each take some time? I don't want to wait for the whole tests to run...
|
April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Wednesday, 30 April 2014 at 13:52:25 UTC, John Colvin wrote:
> On Wednesday, 30 April 2014 at 13:38:28 UTC, Adam D. Ruppe wrote:
>> But still, one person's productivity is too subjective to focus a lot on IMO.
>
> Calculated dishonesty is healthy in a marketing campaign :p
Put another way, one data point is not data but a lot of them is. Every anecdote carries some weight.
And even as one person, there are probably a non-trivial number of people who think roughly the same way and would benefit from...err, from being proselytised? ;)
-Wyatt
|
April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | On Wednesday, 30 April 2014 at 14:58:20 UTC, Ary Borenszweig wrote:
> That's good.
>
> What if you have tests against a database that where each take some time? I don't want to wait for the whole tests to run...
Tests with I/O are not unit tests. And built-in D feature is not called unit-or-somet-other-tests. For integration testing you need some different approach where being able to run separate cases is indeed useful. But it is not a fault of D _unit_ test design.
|
April 30, 2014 Re: D For A Web Developer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Wednesday, 30 April 2014 at 07:14:34 UTC, Jacob Carlborg wrote: > I think one of the great things about Rails and Ruby is all the libraries and plugins that are available. If I want to do something, in RoR there's a big chance there's already a library for that. In D, there's a big chance I need to implement it myself. I like implementing things myself :P That's the question I dread most at meetings now: "is there a gem for this?" idk, in the time it takes to search for and evaluate third party code, I could have just written it myself. Especially since libraries almost always need some kind of customization for our specific case anyway! There's a few exceptions where something is hard to write, but most things just aren't that hard. > But unit tests in D suck as well. A big difference though is the compiler helps you a lot in D. In Ruby, for example, the main reason we use the unit tests (so far) is to help ensure consistency after refactoring something. It catchings things like a renaming we missed, or a removed method still in use. In D, you just recompile and those things are found almost instantly without needing to actually run any code. > How do you mean? It just adds an object oriented layer on top of it. They deliberately avoid the most important parts of a relational database: http://guides.rubyonrails.org/migrations.html "The Active Record way claims that intelligence belongs in your models, not in the database. As such, features such as triggers or foreign key constraints, which push some of that intelligence back into the database, are not heavily used." ORM is something I only like in very small quantities, but ActiveRecord uses it for *everything*, well, except for the things it doesn't even support. The problem here is one of encapsulation and of correctness. If something bypasses the model - which is required for tasks the library doesn't even support and also likely to happen if there's a second app using the data - all kinds of stuff can get in there that is bad. You also have problems like race conditions: account = BankAccount.find(1) account.balance -= 10 account.save! What if two of those run concurrently? I searched the web quickly for this and haven't found a good answer yet... Then, with referential integrity, the docs suggest DIY or getting some third party gem, because their godawful library doesn't really support it. The best it does is offer you a square wheel with the dependent thing. Stupid stupid stupid. When you actually use the database as it is intended, it takes care of these things for you with very easy syntax that works across business logic languages. Nothing new to learn there. > BTW, what should I use in D. I need a library that is database independent and I don't want to write SQL for the common use cases? idk, I use my database.d which has a little bit of overlap with what active record does, but since I generally see ORM as being a nasty anti-pattern and horribly leaky abstraction, I didn't go far with it. There's really nothing to fear with writing SQL, except the cases where the language sucks. (UPDATE and INSERT being so different, and the solutions being different for the various vendors, ugh. That's why I made my DataObject, it gathers the changes together then issues one of those commands. It can also be gotten from a query, making it a kind of simple active record: auto obj = mysql.queryDataObject("select * from foo limit 1").front; obj.whatever = "something"; obj.commitChanges(); // calls UPDATE foo SET whatever='something' WHERE id = ? which also works on joined queries on MySQL btw and offers easy support for multiple primary keys or ones not named "id" (as an argument to commitChanges), something active record as far as i can tell doesn't even try to do, but it doesn't try to fetch child objects or anything like that. I have considered adding child object fetching, but I don't really see the need, it is easy to write a method that does that if you want to.) > I prefer HAML (similar to Jade in vibe.d) but I don't think it's that bad. What do you use? The ruby thing looks like this <span class="foo"><%= @some_value %></span>. For my D stuff, I have two options: 1) create the HTML right in D using dom.d. I like to use this for objects that know how to format themselves and output strictly semantic XML/HTML. The visual styling is then done with CSS. This works better than you might expect! 2) web.d also has a fairly simple replacement system too: <span class="foo">{$some_value}</span> it also supports inserting partials <div html-from="{$dynamic_html}"></div> or <include partial="foo" />, though the include thing takes a wee bit of helper code from the app because it needs to find the html somewhere. And the variable replacement can be piped: {$some_count|plural user users} for example, which is kinda cool. It does NOT support intertwined code. Other things are done with attributes, such as class="if-logged-in" or <ul from="data_thing" /> (infinitely extensible with the server-side DOM). > I don't know how you do you're routing but the first thing I do when generating a new Rails application is to remove the default routing. The default routing opens every public method in a controller to be a routing end point. It's a complete mess. It looks like this root "home#index" get "/users/login", to: "users#login" namespace :admin do resources :users do resources :children end end and so on. It isn't awful (especially now that I get what they mean by "resources"), but my web.d rarely uses explicit routing at all, it figures it out automatically by the names, protection level, and types of child members. > There's a plugin [1] for Rails for generating a form based on a type. I don't understand how anyone can manage without that. thx, I'll take a gander. > It can automatically respond in a couple of formats as well. By default JSON, XML and Erb template. The most basic example will look something like this: Responding with json, xml, and html Just Work with web.d, it figures it out from the static type of the function return value. > You don't think that's because you're used D for quite a while and developed your own web framework. Compared to Rails where you're completely new. Yes, obviously that's some of it, but there's other things that I don't expect to change, especially things like runtime errors for what the D compiler would catch. I had to rename a thing last night. Took two hours to do the db migrations and then rename the classes and update all the files. I'm still not completely sure I did it right too! I've done similar things in D in about 5 minutes, the compiler catches everything so I have confidence. > The biggest problem I have with D is have to do everything myself. I'm getting a bit tired of that. i love that, different strokes i guess. |
Copyright © 1999-2021 by the D Language Foundation