@chebrock said:
I also state anyone taking a year on a web application is not a real developer - it is absurd. A YEAR? Insanity.
Sooooo--; how long has Gmail been in beta again?
@chebrock said:
I also state anyone taking a year on a web application is not a real developer - it is absurd. A YEAR? Insanity.
Sooooo--; how long has Gmail been in beta again?
I guess TRWTF is the fact that whoever wrote and/or deployed the script was ignorant of the user-select CSS3 atribute, its vendor-specific offspring and IE's unselectable HTML attribute.
<div style="user-select: none; -khtml-user-select: none; -moz-user-select: none;" unselectable="on">Can't select me.</div>
@Ice^^Heat said:
You are building a social website in the likes of Facebook. Users can have friends and they can see if their friends are online. If they are, a user can click on "Chat", then a chatbox will open where they can chat with eachother, when they leave, the box closes.
Now, we do this by instancing a chatroom object, and passing the reference to the other user/session by using the CacheSingleton. When the users leave, the reference is set to Null and the chatroom object is disposed by the garbage collector.
No need for a database, just In memory objects. Doesn't seem so bad to me. Or is it just so that Objects are not meant to be shared among requests?
Worker process timeout can be set, and recycling can be enabled, as long that it doesn't interfere with existing chatrooms (which I don't know).
It likely will interfere, as all data inside the Cache and HttpApplication collections is volatile. It will be erased when the application domain is recycled. Data inside the Session collections will be erased as well, if it uses the default InProc (='in process') session state.
This is why you want a database combined with a layer of in-application caching in the Cache collection. That way data will be persisted and your application's state will be preserved across a recycling operation. Again: for reasons mentioned in my previous post the disabling of application recycling should never be an option.
If you want to implement this kind of direct messaging then the best method would probably be to retain a queue of 'received messages' for each person's account. Messages can then be popped from the queue when an account is polled for newly received messages and can be pushed onto the queue when some other person sends a message, ready to be sent back during the next polling event.
The active contents of said queue can forcibly be persisted to the database in the Application_End event and can be reloaded during the Application_Start event to retain state across recycling of the application domain. In addition the working copies of the queues should be handled through the application cache, so that unused queues do not linger in memory but are written out to the database upon cache expiration and are read in from the database when a cache lookup fails.
The messages could be queued along with some form of sender ID so that when a person receives his/her queued messages they can be grouped into chat boxes by sender. Such a set up would allow the sending of messages when a user is not online. In addition real time chatting can be allowed, given a suitable delay between polling events (say; 5 seconds or so) for a message view to keep itself updated.
I'll hazard a guess and say you are stuck in thinking of chatrooms as an explicit object class. In the case of peer-to-peer chatting as in this proposed scenario, the chatrooms are only implicitly present as some form of 'relation' between sender-receiver. There is no reason to build them into the actual program logic.
@Ice^^Heat said:
Plz, WTF-rate my idea. How would YOU do it?
On a scale of 1 to 10, 10 being the most WTF-y, I'd rate this as at least a 9, if only because of the remark of disabling app pool recycling. That's resource starvation waiting to happen. Beyond that, using true singletons is fairly stupid when asp.NET has object stores available that are shared over all incoming requests: the Items collection in HttpApplication and the Cache collection. It's possible to argue in favor of abstracting those collections with generic singleton implementations though; e.g. CacheSingleton<T> and HttpAppSingleton<T>.
As for how I would do it:
Rather than retain Chatroom and Message objects in memory I'd retain a collection of active user, chatroom and message data in a database, with the proper relations (m:1 - message : chatroom, m:1 - message : user, m:n user - chatroom) and additional indices on the proper columns. (Those being user name, room name and message timestamp, probably).
I'd use ajax to pull/push messages, instead of using full postbacks. That way I can limit the amount of messages requested with each poll to only those the client browser hasn't downloaded yet. The ajax requests would be directed at a simple handler (.ashx) that could decompose the XML fragment, query the database for the relevant information and construct a response fragment. To optimize data throughput I'd use asp.net's cache object to keep track of the last 5 minutes or so worth of posted messages and look for messages there first, before resorting to hitting the database. Much the same for the users joining/leaving a room.
@Nandurius said:
Notice a difference? Bingo. The C code is all worried about mundane tasks, where to store items, how items are indexed and other "pointless" work that's only taking time away from thinking about what it is that you want the program to do.
Meanwhile the C code is actually more useful than a basic insertion sort. The Haskell code isn't. Functional languages like Haskell works on lists rather than arrays. Lists don't allow random indexing, meaning the speedup gained from divide-and-conquer algorithms like quicksort is negated by the fact that the actual dividing takes O(n) time, due to having to decompose the list element by element with head or tail recursion.
This is where knowing a bit about the 'mundane' tasks underneath comes in handy. "What" I want the program to do may be important, but it means nothing if the solution I end up with is not usable in practice due to performance issues that are so substantial that just tossing more powerful hardware at the problem doesn't solve them.
Also, I can't help but chuckle at the fact that you argue to move away from the lower level math of how a computer works and then end up heralding functional programming, which is even more math-like and requires a totally different (and to many people unnatural) mindset to work with.
@Michael Casadevall said:
FIrefox goes one step futher and aliases some site names like that, it also allows you to set custom names via the bookmark feature. I don't think IE has any equivelent behavior.
It does actually. Top-level entries in IE's favorites folder can be entered into the address bar by displayed name.
@amischiefr said:
Well, if it was stated as politely as you just did, that would be fine. His insistance to be some 'know it all' and come off as a total dick demeans the point he was trying to make, if any productive point at all.
I graduated in December with my BS in CS, I do NOT pretend to know everything :). Maybe Ragnax knows everything, maybe he's Jesus!!! *shrug* Who am i to say :)
Ragnax, calling people stupid because they did not know of some ISO standard for naming of countries is compltely retarded. Just because you have personally heard of them does not mean that every programmer out there has. Please refrain from commenting on any of my posts. Your ignorant responses do nothing but provoke flaming responses. Were you touched as a child? Do you not get enough respect for your 'vast' knowledge at your job? Well, whatever it is, please keep your ill tempered ignorant voice to yourself ok?
I'm not calling you stupid any more than you were asking if you were stupid: you asked if you or your team were stupid for doing this, I answered that you were stupid for doing this and gave you the reasons. Bearing in mind that your post wasn't made in an all that courteous manner (in fact; it was downright condescending, 'kid'...), I don't think it warranted a more polite answer than the straight-to-the-point I gave you.
As for the ad hominem: that had me laughing. So; it's not okay to call people that ask for it stupid, but it is okay to attack the character of those whose answers you don't like? Pot; meet Kettle. Kettle; this is Pot.
Just for clarification: I am in fact not the bitter or cynical cubicle dweller that you are making me out to be. In actuality I am still attending university: while I do already have a BSc in Computer Science, I'm continuing with a master's degree in Computer Science & Engineering (CSE). As such I certainly do not pretend to know everything, but I do know that the mistakes you made are things that should have been covered in any decent Computer Science BSc program.
As you requested for me to butt out of your thread, I will respect that and stop posting in it. Some parting advice: the real WTF is you. Think about that for a while.
@pitchingchris said:
However, I really wonder how they were generating the xml file. If they were doing it manually, then you can't really trust the xml declaration if they didn't follow encoding rules. For example, I could say encoding="UTF-16" in my xml header declaration and encode the text file in UTF-8 and you would have big problems. Just an example.
Possibly his vendor is using the .NET framework to generate the XML. It has known issues with respect to UTF-8 encoding in its XML writing classes. If you specify the encoding to be used as UTF-8 and configure the XML writer class to write to an internal string buffer instead of to a file, then the XML declaration will (correctly) state UTF-8 encoding, while the actual file will be encoded as UTF-16 as all .NET strings internally use that encoding.
@amischiefr said:
Well, last time I checked XMLBeans was a valid XML parser, but hey what do I know :)
Define valid.
A few months back I had to do some work on a product that used no less than 7 'valid' XML/Xpath/XQuery parsers and processors. None could manage to work correctly with each others output without tinkering, yet they were all 'valid'. The specifications for these standards are so large, ambiguous and vague that subtly differences in implementation can and will happen. And of course 'valid' is also not synonymous with 'bug-free'.
@amischiefr said:
And what is wrong with full text country names? So, you are trying to imply that I, or my team, are stupid because we agreed with the vendor to use United states instead of USA?
@julmu said:
The only thing worse than clueless customers are clueless customers who think that they know everything.
99.9% of customers don't know anything about the thing that they need help with, so the helpdesk has no reason to believe that you are some kind of an expert who knows exactly where the problem lies.
Just let the helpdesk do their job and don't waste their time.
And the only thing worse than clueless customers who think they know everything are clueless helpdesk employees who know nothing (but the script in front of them). It's funny really that you're saying not to waste the helpdesk's time. I'd think it's their job not to waste yours.
Usually I don't even bother with the initial jackass I get support from on the first line and just steer the conversation straight towards a promotion towards the second line. The only thing the first line is usually good for is telling you to set everything to automatic and reboot/powercycle your modem.
@cangulo said:
What is the most efficient, growth-proof and professional way to query for a whole hierarchy of data in a database?
For instance:
table country(country_id primary);
table state(state_id primary, country_id foreign);
table city(city_id primary, state_id foreign);
table street(street_id primary, city_id foreign);
Look up OLAP and data cubes.
@Kelly said:
Yes, flicker is a big problem. There are some things you can do to minimize flicker.
- Try creating sections invisible and then showing them,
- try reducing the use of docking and use Anchoring instead.
- Keep controls to a minimum as there is a big load on the UI as the number of .NET controls increases. I've had to eliminate nested panels and replace images and text with stuff drawn directly on the UI in Paint events.
Using a background thread doesn't help unless you have work to do and want sections to load data asynchronously. There is a huge amout of overhead in calling Invoke() over calling a method directly so your code could be slower if you used a background thread strictly to build UI.
Iirc, all the layout math is still done even if you create sections invisible. Also docking or anchoring doesn't, or atleast; shouldn't, really matter all that much as docking is just anchoring once at the extreme points. Eliminating a lot of controls and manually mucking around with the paint events might not be the most desirable approach either. It will absolutely kill maintainability.
The standard solution is to enable double buffering and make good use of calls to SuspendLayout() and ResumeLayout() to not perform needless layout resizing and repainting while adding/removing or moving/resizing sets of controls.
Indeed, I wouldn't recommend building UI in a background thread either. Not only because the overhead associated with Invoke might end up making it more expensive, but also because it is plain pointless. Why build a section of UI asynchronously, if you have to wait until said building is complete to do anything with it anyway? Generally speaking, it's not like you still need to do something with the old section of UI either: you accessed a new section to do something there instead.
@TheRider said:
Oracle is the only database I know which has a way to find out a new id before adding the row, and thus you are able to use the new id both for inserting the row in table 1, and use that id as a foreign key to table 1 in a new record in table 2.
I'm hoping the Oracle guys were smart enough to increment the ID the moment it is requested, because otherwise: race conditions ahoy!
DB : new ID;
DB->ProcA : ID;
DB->ProcB : ID;
ProcA->DB : (ID, ...);
DB : new ID;
procB->DB : (ID, ...); // Uh-oh!
@Puzzled said:
It was the method used in VB3. Are you sure it won't work?
That depends on your definition of 'work'.
'Work' as in: "It does the job as its supposed to do, without side effects."
Or 'work' as in: "Does it work? Ship it!".
@Puzzled said:
I can't guarantee this, but one approach I would try would be to create a groupbox for each 'screen' and put the needed controls in it. Set all of the Left positions of the groupboxes to -20000 except for the one selected by the buttons. That should hide all but the one you want and let you have any button design you want.
That would leave any control still present in the tab order, just not reachable with the mouse. This kind of solution is really the most bottom of the barrel, imho.
@lpope187 said:
@Ragnax said:I don't think so. There's this little problem with WinForms: controls are 'owned' by the thread that created them, which means no other thread can safely update them. Therefore you must load your controls in the main (STA)thread of your WinForms application. (There are some ways around this limitation, but they involve manually toying with windows message loops etc. and are simply not practical.)
You're probably thinking about OS level threads, but in terms of managed threads it is possible. The code below illustrates my point (I just hacked it together in a few minutes based on what I do normally in my data access components). Looking at Spy++, both the form and the created textbox are owned by the same OS thread. I certainly wouldn't do this in a real app. What I would do is implement an Initialize method on the child control, instantiate the control on the main UI thread, and execute the Initialize method on a background thread.
I'm not thinking of OS level threads. I'm thinking of managed threads. You should take a look at MSDN under System.Windows.Forms.Control.InvokeRequired for more information, but I'll quote the relevant passages for you here:
"Controls in Windows Forms are bound to a specific thread and are not thread safe. Therefore, if you are calling a control's method from a different thread, you must use one of the control's invoke methods to marshal the call to the proper thread."
"In addition to the InvokeRequired property, there are four methods on a control that are thread safe to call: Invoke, BeginInvoke, EndInvoke and CreateGraphics if the handle for the control has already been created. Calling CreateGraphics before the control's handle has been created on a background thread can cause illegal cross thread calls. For all other method calls, you should use one of these invoke methods when calling from a different thread."
Continuing on, your example code does not match your explanation: It is not instancing the controls in the UI thread, it's instacing them within the worker thread. CreateChildControl() is called from LoadChildControlWorker() which, inside LoadChildControlAsync(), is pointed to by workerDelegate and is eventually invoked on a new thread with a BeginInvoke call.
That's funny because, again from MSDN:
"In the case where the control's handle has not yet been created, you should not simply call properties, methods, or events on the control. This might cause the control's handle to be created on the background thread, isolating the control on a thread without a message pump and making the application unstable."
And certainly a control's handle has not yet been created before you entered the background thread when you're actually creating it on said background thread and are setting properties on it before attaching it to a child control on a form (which is when the handle is created, iirc). It's a miracle this whole thing isn't exploding in your face, because you've been dodging bullets with regards to violating thread safety.
Also, your worker thread implementation looks like a reinvented square wheel. Take a look at the System.ComponentModel.BackgroundWorker class for a standardized solution.
@lpope187 said:
Loading all the child controls at once can be an issue. The right solution (although more difficult to program) is to have the primary child control loaded on the main UI thread and then load the secondaries on a background thread. That way you get fast initial load and fast switching but you have to deal with synchronization and the rare case where someone wants to load up a secondary before the background thread has processed it.
I don't think so. There's this little problem with WinForms: controls are 'owned' by the thread that created them, which means no other thread can safely update them. Therefore you must load your controls in the main (STA)thread of your WinForms application. (There are some ways around this limitation, but they involve manually toying with windows message loops etc. and are simply not practical.)
@swaj said:
Honestly, I don't see why you couldn't just use panels and then toggle the visibility based on which button they press, for example:
Left side: button1,button2,button3,button4,button5 -- you can change the properties on these to make them big, like spybot S&D, add graphics, etc.
Right side: panel1, panel2, panel3, panel4, panel5 -- these panels are all the same size and same docking and stacked on top of each other, and then you can just toggle the "Visible" property on them based on which button is clicked.
This method can be a little painful to develop only because you have to keep "sending to back" on the panels in your development interface, but it will accomplish your desired functionality, and it's not really a WTF way of doing it. If you want some sample code, I could throw together a small project for you to illustrate the idea.
As a secondary option, you could purchase a control from somebody that does this type of thing. Krypton Navigator comes to mind. Check it out on http://www.componentfactory.com/. It's pretty cheap, and it works very well. I've used it in the past.
Cheers!
OP was asking for a non-wtf winform application. The fact that your solution has maintainability and scalability issues should clue you in on the fact that it is, in fact, a WTF.
As I've tried to explain before; more or less the only 'correct' way to do this is to encapsulate all your 'tabsheets' into separate user controls and then dynamically load the relevant user control onto the form. Personally I think the MDI approach is a good solution as well, but it wasn't what the OP was looking for. (Perhaps though, it is what he should have been looking for...)
@alegr said:
@Stilgar said:So first we get the bytes then we pack them into a stream and unpack them into bytes again... cool! And what is a buffer needed for anyway.
I was quite annoyed because this article is supposed to teach others how to do this.
Could it just be that memory stream has different properties than HTTP data stream? For example, it never fails, and allows random access, and its lifetime is not limited by any TCP timeouts? Maybe you don't understand some fine points?
Actually, there's a very good use for using a buffer instead of directly passing in the entire memory stream to the output stream. The reason for it lies with the fact that asp.NET usually buffers the entire output stream in memory before starting to send it to the client browser. Using a buffer you can push bite-sized chunks into the output stream and flush those to the client browser manually, chunk by chunk.
Ofcourse, even though the concept of using a buffer isn't that bad, the implementation in this case is.
@chebrock said:
Two points. GOF does mention MVC in the introduction. Second, you're right, it's not specifically mentioned as a graphical control, but it is tied to the concept of input, not routing.
Routing is the changing of view (since pages are views), which is part of a controller's job: changing the view and/or model based on the input the controller receives.
@chebrock said:
Web MVC is an insufferable concept that must die. Once upon a time the GOF wrote about a pattern called MVC. Not that complicated, but useful. Now, somehow, it became the basis for all web based frameworks and actually has little to do with the original MVC. A controller used to be a graphical control that responded to both the changes to the data, and to user events. Now its some routing mechanism for web-requests. It's stupid. Stop it now.
I suggest taking a look at the original paper on MVC by Burbeck. He clearly states that:
"The view manages the graphical and/or textual output to the portion of the bitmapped display that is allocated to its application. The controller interprets the mouse and keyboard inputs from the user, commanding the model and/or the view to change as appropriate. Finally, the model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller)."
I don't see any mention of the controller being a graphical control.
What you describe matches closest to MVP (model-view-presenter), a derivative of MVC that more tightly binds the MVC concept of controller and view together into the presenter. The view in MVP is merely the common interface by which a set of presenters can communicate with the model. This is the paradigm the asp.net framework uses.
Think about the following as well: In web programming the MVC view represents the resulting page. It is one of the controller's tasks to command the view to change. That makes it natural for the controller to (partly) be a routing mechanism for requests. Infact that's all a controller is ever supposed to do: control, not act!
@chillenious said:
Read the first (and free) chapter of Wicket In Action if you want to have my take on it.
Congratulations: you've managed to make a Java clone of asp.NET's MVP (Model-View-Presenter) architecture, although with a few flaws snuck in. Flaws like requiring the manual instancing in the page's backend code of controls/components present in your HTML layout and manually linking them through a weak string-matching reference. Or flaws like dismissing RESTful, aka state-preserving, pages as a simple optimization and only treating the naive case of directly preserving state in the URL. (Hint; take a look at asp.NET's viewstate system which works through an encrypted hidden form field which is automatically (de)serialized for the application programmer by the framework...)
As for your framework's usefulness; enterprise level asp.NET developers have been anxiously anticipating the asp.NET MVC framework (to ship with VS2008 SP1, iirc) for some time now, as it will allow for an altogether better decoupling and tiering of the various application components, making the development of modularized 'plugin' web applications much easier and simultaneously allowing for better integration into unit test frameworks and more elegant handling of asynchronous postbacks.
The argument you make against MVC is actually laughable when considering the section you write on AJAX in the first chapter of your book. An MVC approach would have the Controller processing an Ajax request, by manipulating data retrieved from the Model and forwarding it to the View to format into whatever the client website expects back (XML, XHTML, etc.). Much more elegant than having to manually match tags in pages to do partial page updates on a page that serverside is still interpreted as a complete synchronous postback as you are suggesting!
Basicly, Wicket is a case of reinventing the square wheel and a case of 'too little, too late'.
PS:
You might also want to contact your digital distributor; the PDF of the first chapter that you offer up for download contains no copyright information on Google, which I believe is quite the prerequisite for a commerical work that includes images of copyrighted material like Google's website.
@noodle said:
It was spending time during the download, before anything got uncompressed or checksummed etc. I'm not suprised if the decompression/validation takes a little time... but downloading?!
If I had to take a wild guess I'd say the update manager uses home-grown networking code which relies on some really bad method of socket communication. It's probably sitting in a busy spin polling for new data on the inbound socket.
My favorite has to be "Everything is varchar".
In particular when said varchar is universally chosen to be of a maximum length too small to fully store the application's actual data fed to the database. Bonus points if the application is then set up to silently fail and not inform you of truncated strings, or tosses out some nonsensical error sending you off on a wild goose chase in a completely unrelated direction.
@talaxor said:
Hi all. I don't really post much here, so I know I'm prolly gonna bungle this but here goes. I have a program I'm writing in c# that I want to display different "screens" when buttons in a left hand navigation type area are clicked. (Think something similar to frameset navigation on web pages, or more like the UI to SpyBot) What's a good non-wtf way to do this? The only thing close to what I want would be to abuse the tab control, and I don't really want to use it because I don't want tabs along the top, I want buttons close to the left hand side. (BTW, this is being built using VS 2008, and is not a WPF application). I've done coding for years, but mostly console, services, or simple winforms applications, so I'm a little lost on the right way to do this. Thanks in advance for your suggestions.
The dead-obvious solution to your problem is to have usercontrols dynamically added to and removed from some container control.
IIRC this is as simple as emptying the container control's control collection and manually instantiating the requested user control and adding it to the collection instead. Something like:
container.SuspendLayout();
container.Controls.Clear();
container.Controls.Add(new MyUserControl());
container.ResumeLayout();
There's absolutely no need for any WTFs resulting from hacking away at the Tabsheet control.
@NathanW said:
I don't think they knew how to use a Case statment, I know that the above code will do the same as a Select Case but a least case statments make your code a hell of a lot easier to read.
And I don't think you know how to read APIs:
The variation of System.String.Compare used here compares to substrings of given length starting at the given positions in the compared strings. Switches in .NET only allow constant expressions to be used as case labels, so while .NET does allow constant strings, there's no way besides an 'elseif' construct to handle this problem.
The real WTF is the use of System.String.Compare when System.String.StartsWith should have been used.
@Pope said:
I guess I should be asking if there is another tool like the Google Language API that I could use server-side.
See: http://code.google.com/apis/ajaxlanguage/documentation/#fonje
Just use the HttpRequest object in the .NET framework to talk to the Google Language API from the server side.
@cBradley said:
Which do you think is a better method of forming a boolean test:
A:
boolean someTest(){
boolean retVal = false;
if(someCondition){
retVal = true;
}
return retVal;
}
B:
boolean someTest(){
if(someCondition){
return true;
}
return false;
}
C:
boolean someTest(){
return someCondition;
}
Where someCondition may be a complex statement.
Imho none of them are a good method when you expect someCondition to be a reasonably complex statement. Complex guard expressions that run for several lines in cases A and B do not make for readable code. Neither does a complex expression all crammed onto a single return in case C.
A better idea would be to split the evaluation of someCondition into smaller parts, incrementally dismissing cases on a logical basis. Meaning:
boolean someTest(){
// Explain part of condition
if (!somePartOfCondition)
return false;
// Explain other part of condition
if (!someOtherPartOfCondition)
return false;
// Explain what cases remain
return true;
}
I guess that matches closest to type B.
@Pope said:
I would love to be able to add attributes to the A tag; however, it's inside a .NET control. I'm trying to dig into the System.Web.UI.WebControls.MenuItem object and extract that A tag so I can add attributes to it.
There's no way to access the anchor tag serverside as it is HTML content that is only generated during the RenderContents method of the System.Web.UI.WebControls.Menu control with which your MenuItem object instance is associated. System.Web.UI.WebControls.MenuItem itself doesn't even derive from System.Web.UI.Control, meaning it is not control in the ASP.NET sense to begin with!
I'm interested in [i]why[/i] you'd need to decorate that anchor tag with attributes in the first place. The fact that it is this hard to get something like this done within the scope of the framework should've already told you the idea probably belongs in the 'bad things' category. Probably you are trying to implement some kind of functionality that you think has to be solved by manually manipulating the anchor tag, while the framework may already provide a better, established way of handling the problem at hand (as is usually the case with .NET's web controls).
Still, if you insist on hacking away at the anchor tag manually, you could try deriving a custom control from Menu and overriding its RenderContents method. However, as I mentioned: most likely, that is [i]not[/i] the correct way of handling the problem. You can forget about taking the easy path of inheriting from MenuItem and overriding a few methods and/or properties: it's a sealed class and can not be inherited from.
OP is right; there is a better way:
if (foundControl != null)
{
ITextControl textControl = currentControl as ITextControl;
if (textControl != null)
{
textControl.Text = foundControl[_displayLabelColumn].ToString();
}
}
All ASP.Net controls with a Text property implement (or atleast; should implement) ITextControl. Furthermore, a little known property of C#'s as operator is that it returns null if it can not cast the specified variable to the specified type.
@DaEagle said:
I love the one that comes up every now and then in the designer:
A <insertclasshere> cannot be coverted to a <insertsameclasshere>
I know why it happens... still seems like a WTF though!
Be happy you don't have to work with Delphi for .NET. I once had it spit back out at me that it was "unable to cast object of type System.Int32 to type System.Int32." This wasn't just a glitch in a designer; It was consistently reproducable when passing arrays (of any type) between .NET framework libraries and libraries written in Delphi for .NET in the fashion as dictated by Borland...
@Zemyla said:
Actually, the real WTF is the "klik hier" things, which are a no-no when developing for vision-impaired users.
Forget 'vision-impaired'. Those kind of links are a no-no period.
The philosophy behind hyperlinks is that the link takes you to information related to the link's own text. For that reason links labeled "click here" or similarly should never be used. A more correct approach in this case would've been to turn "Stel uw vraag dan aan ons" ("Then ask us your question") into a hyperlink instead.
Regretably 9/10th of the idiots, pardon; 'web designers', out there don't get this. Probably because it doesn't quite 'feng shui' with the general design of their site, or whatever.
@Jonathan Holland said:
No need to be racist. I've worked with some excellent indian programmers. The good ones come here. The crappy ones tend to stay there.
Here is my fix:
var zipCodebtnAjaxContinue = document.getElementById('zipCode_btnAjaxContinue');
if (zipCodebtnAjaxContinue)
{
zipCodebtnAjaxContinue.onClick = CheckZipClick();
}
Might want to remove the parentheses after CheckZipClick there. If I'm not mistaken, your current solution assigns the result of the evaluation of the function CheckZipClick to the onClick event handler, rather than the function itself.
@ender said:
@MarcB said:Beats me why paying off the credit card debits my account immediately, but the payment gets dated for "next business" day on the CC account. Probably has something to do with the bank hanging on to the money for a few hours so they can earn a couple pennies interest on it somewhere.My bank actually has this described somewhere on their site - when you transfer money outside business hours, your account is charged immediately, but then the money is placed in some temporary internal account where it stays until the business hours, when it finally ends on the target account.
This messing with the dates is common practice for a lot of banks. Allegedly, the interest they gain from this dirty little trick is what they finance their financial traffic with. Recently a few customers of Dutch bank ABN Amro got into financial trouble due to this practice as well and they had to 'lawyer up' in order to have the bank strike the interest related to their accounts being temporarily in the red. Luckily for EU citizens, the EU is outlawing this practice and member states should have the related EU guideline implemented in law by November 2009.
@savar said:
I think rewrite rules are stupid anyway. Maybe this programmer was making an ironic commentary on the vanity in web development?
Sadly, I don't think so. The remainder of the site is a convoluted WTF of javascript 'framework'. It even relies on javascript for basic page layout. To top it off this 'framework' seems to rely on user agent string based browser detection.
The website simply reeks of 'incompetent web monkey'.
@MasterPlanSoftware said:
@Nozz said:No, that's not what I said. He said he that he has return statements a throw, not after a catch. Therefore, I'm suggesting that the IDE allows this:
public object foo (int a)
{
throw new Exception("Blah");
}His IDE would force him to do this:
public object foo (int a)
Which would actually cause a compiler warning (in C#, anyway).
{
throw new Exception("Blah");
return null;
}I would kind of hope it returns a warning... who would write code like that?
If you have a function it has to return a value on a code path. That is what the warning says.
Why would you write a function that only throws an exception?
It happens more often than you might think in large frameworks with multiple intercommunicating components relying on contracts through interfaces:
throw new Exception("This member has not been implemented yet.");
@Carnildo said:
@JamesKilton said:So, where is the WTF?
It's only transposing half the matrix: 6 changes for 16 elements.
Maybe this was a necessity and a VERY VERY poorly named function?
@ShadowWolf said:
@Ragnax said:@bighusker said:
@ender said:@bighusker said:Do other text editors have this problem? I'd imagine there has to be some reasonable workaround for this.Notepad is awful and has plenty of bugs for a simple friggin' text editor. First of all, there this ridiculous bug as described on the snopes message board: http://msgboard.snopes.com/message/ultimatebb.php?/ubb/get_topic/f/56/t/002928.html. How in the hell do you even pull something like that off?This is not a bug in the notepad, but simply the way IsTextUnicode function works. And the limitation's been known for a long time.There is. It's called; Letting the user decide which encoding to use. Seriously; What's so hard about popping up a dialog box that states the application isn't sure what format the file has and asking the user to decide for it?
Windows and its bundled applications are made to be usable by braindead idiots, but even that category of user wouldn't have problems with something like that, would they?
Because when a user opens a text file and they see a dialog that comes up saying "This file is saved in an unrecognizable file format, please select the one you want" they are obviously going to very familiar with the encoding of that file.
If you knew much about language encoding issues, I doubt you'd say this. If you do know much about language encoding issues and you're saying this then you're just being elitist.
There is no "right" solution because every solution is either an annoyance (every time you open File "X" you recieve a warning about how it may not have opened correctly despite that it worked fine) or a presumption of knowledge.
They don't need to be familiar with the actual encoding of the file. Just provide a short decoded sample for all possible encodings. A similar solution exists for the BitTorrent client Azureus and it works wonderfully well.
@bighusker said:
@ender said:@bighusker said:Do other text editors have this problem? I'd imagine there has to be some reasonable workaround for this.Notepad is awful and has plenty of bugs for a simple friggin' text editor. First of all, there this ridiculous bug as described on the snopes message board: http://msgboard.snopes.com/message/ultimatebb.php?/ubb/get_topic/f/56/t/002928.html. How in the hell do you even pull something like that off?This is not a bug in the notepad, but simply the way IsTextUnicode function works. And the limitation's been known for a long time.
There is. It's called; Letting the user decide which encoding to use. Seriously; What's so hard about popping up a dialog box that states the application isn't sure what format the file has and asking the user to decide for it?
Windows and its bundled applications are made to be usable by braindead idiots, but even that category of user wouldn't have problems with something like that, would they?
@mrsticks1982 said:
It now gives Yahoo the power to sue every other company that produces for the web because they are infringing on a patent.
Don't you mean 'the power to sue every other [i][b]USA-based[/b][/i] company that produces for the web'? European web developers, present company included, would laugh at this, I bet.
Indeed. Situations such as user rights management spring to mind, where the indeterminate state means as much as 'inherited from ---'. It's an easy way to graphically present inherited user rights from usergroups, higher levels in a rights architecture, etc. etc.
@Tweenk said:
Huh? You can change the type of an element with CSS display: property. Otherwise, there would be no way to legally implement i.e. a one-line search form in a table cell. So everything there is to be done is to change the the CSS for this anchor to display: block.
Err.. no. What you're suggesting still does not produce valid HTML. You'll still have block level elements inside inline level elements.
The proper way would be to replace all block level tags within the anchor tag with their inline level equivalent (In the case of <div>, that would be <span>. Possibly <p>, but I'm not sure about that.) and then through css give all those inline level tags, including the anchor tag, the display:block property. However, I've had IE bug out before on anchor tags that get display:block. Their pseudoclasses would stop working and in some instances they lost the functionality of being a link as well, just as the OP describes.
Probably the best way to solve all these problems at once is to change the anchor into a regular <div> element and just give that an onClick event that redirects to another page. Then again, that would shut out browsers that don't have javascript or have it disabled. Choices, choices...
Tried it and ditched it as it didn't allow my third party components to integrate with the designer. For a language like Delphi, which is all about RAD, that just about kills its usefullness, possibly degrading it to those who wish to only experiment with programming or those who are taking classes on programming and require a first-time practical OO language. (Though I doubt those specific users could find their way through the forest that is the IDE's UI anyway.)
@KenW said:
@Ragnax said:
The hotfixes? BDS 2005 had three official updates and none of those really fixed any usability problems. Infact, installing update 3 on my machine actually toasted the help file and I had to use 3rd party tools to manually recompile and reintegrate it into the help system.
Three official updates? There have been 9 hotfixes released, IIRC. Enough so that they bundled them into the hotfix rollup. And none of the hotfixes caused any problems when installed.
@Ragnax said:
It's also no wonder you're having little problems with BDS 2005; You're only loading the Delphi personality (and I assume only the Win32 one at that). Try loading the Delphi.NET one and see how well you fair. I can almost guarantee that your user experience will be less than satisfactory. Contrary to what Borland would probably like to tell you, cutting out over two-thirds of an expensive product (with a draconian license to top it off) does not constitute 'fixing the product'. (Actually, I bet it's even more probably they'd just try to shovel 2006 on you.)
Where did I say that? I was discussing startup speed. Nowhere did I say I only use the Delphi personality (or Win32). I use all of the personalities (well, rarely the C++ - why punish myself?).
On my development machine (2GHz AMD Turion 64, 1GB RAM, 100GB HDD) BDS 2005 with [b]only the Delphi personality[/b] loading takes approximately 15 seconds to initially start; the delay is caused by the fact that some of the refactoring support is provided using .NET, and the framework has to be loaded. If I immediately exit and restart it, the IDE starts in ~3 seconds.
@Ragnax said:
Startup time of the BDS IDE when using the Delphi.NET personality was approx. 1,5 minutes on my dev. machine (1.8GHz Pentium 4, 2GB RAM). Afterwards, opening a project of about 20kloc to work on would take an additional 15 seconds. This in contrast to VS 2005, which manages to start up perfectly fine in 25 seconds, including loading a project in the same order of size.
Bull. If that's the case, you're running everything else on your machine simultaneously. I can load the full BDS 2005 (all personalities) in less than a minute, while VS Express takes about 2 minutes (I say about because I haven't timed it, so I'm approximating. I'll be glad to time it when I get back to that machine tonight, though.
@Ragnax said:
Oh yeah, as for Code Insight, code completion, ctrl+spacing; It's true that it works a lot better on the Delphi-Win32 personality, but when using the .NET personality you can count on running into heaps and heaps of weird quirks.
When will it start? I haven't experienced it at all yet (in over a year of using BDS 2005).
@KenW said:
@unklegwar said:Soooooooooo....YOU fudged up the file conversion with a bad regex and created a corrupted/invalid format, and the IDE is the WTF? Wow.
That would be like blaming the reader for being unable to read/comprehend a book that hasn't been properly punctuated.
Finally, someone who makes sense. :-)
I've been a Delphi developer since Delphi 1 was released (prior to that I worked in C/C++/Clipper). Delphi 2005 is a great product, once you've installed the hotfixes that have been released.
The mismatched line endings problem has existed for quite some time now. It's a problem with the compiler. It's also well known, and could probably be found with a Google search on "Delphi missing blue dots"; I didn't try the search myself, but I'd suspect it would find enough info to point out the two causes of the problem. (Duplicate file on search path than the one opened in the editor and mismatched line endings.)
On my development machine (2GHz AMD Turion 64, 1GB RAM, 100GB HDD) BDS 2005 with only the Delphi personality loading takes approximately 15 seconds to initially start; the delay is caused by the fact that some of the refactoring support is provided using .NET, and the framework has to be loaded. If I immediately exit and restart it, the IDE starts in ~3 seconds.
The Code Insight stuff works fine for me, too. As for API parameters, there's a registry setting you can add that allows Ctrl+Space to show you the proper parameters and their types.
All in all, BDS 2005 is a great product. I've used Visual Studio Express (C#) for some projects that needed the .NET 2 framework, and it's a piece of crap compared to the BDS IDE. Talk about being extremely slow!
The hotfixes? BDS 2005 had three official updates and none of those really fixed any usability problems. Infact, installing update 3 on my machine actually toasted the help file and I had to use 3rd party tools to manually recompile and reintegrate it into the help system.
It's also no wonder you're having little problems with BDS 2005; You're only loading the Delphi personality (and I assume only the Win32 one at that). Try loading the Delphi.NET one and see how well you fair. I can almost guarantee that your user experience will be less than satisfactory. Contrary to what Borland would probably like to tell you, cutting out over two-thirds of an expensive product (with a draconian license to top it off) does not constitute 'fixing the product'. (Actually, I bet it's even more probably they'd just try to shovel 2006 on you.)
Startup time of the BDS IDE when using the Delphi.NET personality was approx. 1,5 minutes on my dev. machine (1.8GHz Pentium 4, 2GB RAM). Afterwards, opening a project of about 20kloc to work on would take an additional 15 seconds. This in contrast to VS 2005, which manages to start up perfectly fine in 25 seconds, including loading a project in the same order of size.
Oh yeah, as for Code Insight, code completion, ctrl+spacing; It's true that it works a lot better on the Delphi-Win32 personality, but when using the .NET personality you can count on running into heaps and heaps of weird quirks.
So, all in all BDS 2005 is a great product, yes, if you are looking for nothing other than a new IDE for maintaining your legacy Delphi-Win32 applications. But wait; Didn't you have Delphi 7 for that?
@unklegwar said:
@Gabelstaplerfahrer said:Delphi 2005 - it's just my daily glimpse of what hell could be like.
At first it looks alright, seems to work for a while, but then... all kinds of little annoyances start to surface. On their own, they are just little bugs. But together they create an environment that could make programmers go postal. Today I found a new one, it's really ugly, let me tell you.The conclusion: it appears that the IDE shows files with corrupt line endings the way you'd expect, a #13 without #10 will still be shown like a #13#10 line ending. So the code looks alright and compiles correctly.
But as soon as you want to debug, you'll notice the blue dots (in the margin, to show which code was compiled) appear in strange places. It is impossible to step through the code in a normal way. I've had this blue dots problem before, at the time it was caused by looking at another .pas file with the same name as the actually compiled file, and the IDE thought it was this compiled file. So I checked and double checked but this wasn't the case. I finally found out about the line endings. They were corrupted because I used a broken regex to convert an SQL script to Delphi strings :(
Soooooooooo....YOU fudged up the file conversion with a bad regex and created a corrupted/invalid format, and the IDE is the WTF? Wow.
That would be like blaming the reader for being unable to read/comprehend a book that hasn't been properly punctuated.
The WTF is the fact that the IDE and the compiler don't warn you about the file being corrupt, I think. I've run into this a few times myself (related to files going corrupt when the IDE would lock up on me).
If you think maintaining legacy Delphi code is bad with Delphi 2005, try this one; interopping assemblies written in Delphi.NET with C# assemblies. You'd be surprised at the amount of loopholes you'd have to jump through to get some things working, while other things will simply never work.
For me, a big WTF came from an ASP.NET webservice, which serialized custom objects to send to the clientside facade (which of course Delphi 2005 automatically generates...). Sending objects themselves; no problem. Sending arrays of objects; Hey, why do all my arrays have 0 elements when retrieved by the client?! Answer; Because Delphi internally does something really disgusting, leading to incompatibilities between .NET's built in System.Array and Delphi's own array implementation, horribly messing up the results from the auto-generated clientside delegate function that calls the actual webservice function. The kicker; The Delphi one is (atleast documented) to be converted to a System.Array when compiling anyway...
That wasn't the biggest WTF I had with Delphi 2005 though. The biggest one came when I had to juggle with some array indices (to get a Delphi array 'talking to' a System.Array, ironically) and ended up having to retrieve the 0-th element for some reason. So we retrieve myArray[0], at which point the compiler screws up and claims 0 is not a System.Int32. Okay... So maybe it can't handle const ints for some reason? We create a new System.Int32 myIndex = 0, then retrieve myArray[myIndex] at which point the compiler claims that the type System.Int32 is not compatible with the type System.Int32.... WTF?! (I probably could have submitted that one to popup potpourri, but by that point I had already grown apathic to Delphi WTFs.)
Screwups like the above won't really seem all that weird anymore once you've used an assembly inspector tool to look at the inside of a Delphi.NET generated assembly though. Borland used some rather... interesting?... ways to maintain the classic Delphi way of working with units, unit global variables, etc. Let's just say that it's a miracle System.Reflection isn't completely broken on Delphi.NET generated assemblies. And yes; it is partially broken, which gives plenty of WTFs when working with large System.Reflection dependent C# frameworks.
Then there's Borland's design decision when it came to namespaces. You see; the Delphi.NET and regular .NET namespace differ. Yes, they're different. Delphi 2005 'automagically' gives a class a C# namespace by chopping off the last section of the name of the unit the class resides in. The catch here is that code generated in Delphi.NET still needs that last section, while C# code must have it removed. That means happy time when dealing with embedded resources as well.
And that's just the compiler and generated code. Don't even get me started on the IDE quirks. Arbitrarily deciding to lock up, erasing or corrupting code files, randomly unregistering assembly references from your projects, randomly resetting paths to resource files to places where said resource files do not exist, randomly popping up dialog boxes stating something being a null reference, etc. etc. The list goes on and on and on.
Eventually (as in 'after several months of time') I figured out a few things to get it reasonably (as in 'no longer mind-destroying') stable though;
Disable Together support on your project and use task manager to assign the IDE process to a single CPU. Apparantly a slew of the more exotic quirks are simply caused by non-threadsafe code, while Together can be attributed a 150MB memory leak that develops over time. As it turns out, the randomly popping up dialog boxes with null references are caused by code completion. With that shut off you might just as well be using freakin' Notepad to code.
Borland; From hero to zero.