D For A Web Developer

Adam D. Ruppe via Digitalmars-d digitalmars-d at puremagic.com
Wed Apr 30 08:04:52 PDT 2014


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.


More information about the Digitalmars-d mailing list