I found the Wikipedia entry on the soft coding anti-pattern terse and confusing. So what is soft coding? In what settings is it a bad practice (anti-pattern)? Also, when could it be considered beneficial, and if so, how should it be implemented?
Short answer: Going to extremes to avoid Hard Coding and ending up with some monster convoluted abstraction layer to maintain that is worse than if the hard coded values had been there from the start. i.e. over engineering.
Like:
SpecialFileClass file = new SpecialFileClass( 200 ); // hard coded
SpecialFileClass file = new SpecialFileClass( DBConfig.Start().GetConnection().LookupValue("MaxBufferSizeOfSpecialFile").GetValue());
The main point of the Daily WTF article on soft coding is that because of premature optimization and fear a system that is very well defined and there is no duplicated knowledge is altered and becomes more complex without any need.
The main thing that you should keep in mind is if your changes actually improve your system and avoid to lightly label something as anti-pattern and avoid it by all means. Configuring your system and avoiding hardcoding is a simple cure for duplicated knowledge in your system (see point 11 : "DRY Don't Repeat Yourself" in The Pragmatic Programmer Quick Reference Guide) This is the driving need behind the suggestion of avoiding hardcoding. I.e. there should be ideally only one place in you system (that would be code or configuration) that should be altered if you have to change something as simple as an error message.
Ola, a good example of a real project that has the concept of softcoding built in to it is the Django project. Their settings.py file abstracts certain data settings so that you can make the changes there instead of embedding them within your code. You can also add values to that file if necessary and use them where necessary.
http://docs.djangoproject.com/en/dev/topics/settings/
Example:
This could be a snippet from the settings.py file:
num_rows = 20
Then within one of your files you could access that value:
from django.conf import settings
...
for x in xrange(settings.num_rows):
...
Soft-coding: it is process of inserting values from external source into computer program. like insert values through keyboard, command line interface. Soft-coding considered as good programming practice because developers can easily modify programs.
Hard-coding. Assign values to program during writing source code and make executable file of program.Now, it is very difficult process to change or modify the program source code values. like in block-chain technology, genesis block is hard-code that cannot changed or modified.
The ultimate in softcoding:
const float pi = 3.1415; // Don't want to hardcode this everywhere in case we ever need to ship to Indiana.
Related
I personally would say that a boilerplate is like a single snippet that can be pasted. But there are repos like this one: https://github.com/h5bp/html5-boilerplate
So, what should be the difference? Google search doesn't really provide an useful answer. Since the actual dictionary definitions of these terms are completely different from their meaning in programing.
Boilerplate: repetitive stuff that is necesssary, yet you get to type it out again and again and again, and it just feels like it wastes time to have to do it so many times. Most frameworks try to reduce boilerplate as much as possible while still being flexible enough to cover all necessities.
Scaffolding: a starting point for your program (or part of it), generated by some tool. You take it and tweak it to your needs. This combats the boilerplate problem by automatically generating some of it so you don't need to type it by hand.
Boilerplate: static template or templates likes 'sample code'. Files for re-useing in project by copy-paste, and then modify it as the need.
Scaffolding: templates with some placehold (variable), used by some tool(like project widzard) to generate the start point of project. For example the npm init.
I was wondering if there were a way to compute the size of a reg in Verilog. I researched it quite a bit, and found $size(a), but it's only in SystemVerilog, and it won't work in my verilog program.
Does anyone know an alternative for this??
I also wanted to ask as a side note; I'm having some trouble with my test bench in the sense that when I update a value in the file, that change is not taken in consideration when I simulate. I've been told I might have been using an old test bench but the one I am continuously simulating is the only one available in this project.
EDIT:
To give you an idea of what's the problem: in my code there is a "start" signal and when it is set to 1, the operation starts. Otherwise, it stays idle. I began writing the test bench with start=0, tested it and simulated it, then edited the test bench by setting start to 1. But when I simulate it, the start signal remains 0 in the waveform. I tried to check whether I was using another test bench, but it is the only test bench I am using in this project.
Given that I was on a deadline, I worked on the code so that it would adapt to the "frozen" test bench. I am getting now all the results I want, but I wanted to test some other features of my code, so I created a new project and copy pasted the code in new files (including the same test bench). But when I ran a simulation, the waveform displayed wrong results (even though I was using the exact same code in all modules and test bench). Any idea why?
Any help would be appreciated :)
There is a standardised way to do this, but it requires you to use the VPI, which I don't think you get on Modelsim's student edition. In short, you have to write C code, and dynamically link it to the simulator. In the C code, you can get object properties using routines such as vpi_get. Useful properites might be vpiSize, which is what you want, vpiLeftRange, vpiRightRange, and so on.
Having said all that, Verilog is essentially a static language, and objects have to be declared with a static width using constant expressions. Having a run-time method to determine an object's size is therefore of pretty limited value (since you should already know it), and may not solve whatever problem you actually have. Your question would make more sense for VHDL (and SystemVerilog?), which are much more dynamic.
Note on Icarus: the developers have pushed lots of SystemVerilog stuff back into the main language. If you take advantge of this you may find that your code is not portable.
Second part of your question: you need to be specific on what your problem actually is.
My situation, as some background:
I'm writing a small javascript library which uses window.requestAnimationFrame to perform its animation loop. Because that function isn't standardised across the browsers yet, internally in the library it creates a polyfill-ish function in a closure.
var requestAnim = window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| ...
|| function () { ... };
The issue here is that this makes it quite hard for me to test this code now. Previously, when it was using setTimeout, I would override that global function in the tests to simulate a number of frames passing synchronously.
Anyway, to the point of the question:
Right now, it seems like my options are either to leave some of my code untested, or to add extraneous features to the library with the sole purpose of making it easier to test. Neither of these options sound that great to me.
Without worrying too much about my specific case, in general, what should you do in this situation?
Yes, it is ok.
We don't write tests for the sake of testing. Testing is an acknowledgement of the fact that we aren't brillant enough to write and maintain code perfectly without safety checks. All test code serves one purpose and only one: to make a better product. This is true whether it lives in the /test folder or in the /src folder. Therefore it is a mistake to think "This is never called in production, therefore it is wrong to put it into /src!"
To be sure, there are other trade-offs to make, e.g. size (in an embedded product it makes a lot of sense to try everything you can to keep the /src folder small). But that is a completely different reason than merely "It's test-related".
I'd say it's fine to add testing code (unless some micro-optimisation is something you're testing). As Kilian was saying, nobody is perfect; this is the reason we do testing in the first place.
I +1d Kilian's answer, but I'd like to add my own ideas too:
In general, what situations would there be code that you cannot (with ease) test? This would be code that only runs under conditions, which you can't re-create on your testing machine? Perhaps it would be easier to set a variable to decide whether this code should run or not, then you can set a breakpoint and change this variable when debugging (in your JavaScript case, using Firebug or Chrome's developer tools?)
Or, like you say, add some testing code - a set of flags maybe at the top of the script, to keep it neat? Then your if statements could be something like
if(shouldRunThisCode || isTestingThisCode) {
doThisCode();
}
In short: Ofcourse it's fine to add code for the purpose of testing. I can't think of any scenarios where testing the code will require adding much code at all though. If the code is implemented and intended to run at some point under certain conditions anyway, it can never be too hard to test.
In general, code that is hard to test is badly written.1 It is superior to find the design problems your test difficulties are telling you about and fix those than to add code "just to make testing easier". Sometimes we do that anyway, because we construe the design problems as too difficult to fix -- but it should be the second choice. In your case, it sounds like the bad design you're exposing is in a library outside your control. In this case, adding code "just to make testing easier" is probably the best choice; you are unlikely to have enough control over an external library to improve its design.
In my Cocoa development, every so often I include a header into a source file so I can use a particular class in it. But then later I delete that code from the source file, and forget (or don't really want to worry about) deleting the corresponding #import.
With time, a lot of redundant #import lines pile up in my source files, throughout the codebase.
Now, I know that these lines cause no harm, but is there any easy way to get rid of them automatically? At least it would make the top of every file cleaner ;)
There's a tool that does this for C and C++, but as far as I could tell, it doesn't yet support Objective-C. I've filed a ticket to ask for that.
nothing comprehensive off the shelf comes to mind.
1) JetBrains' AppCode may help. It's quite young at this time (e.g. not even 'beta', but it is publicly distributed), and doesn't fully understand structures of includes and nontrivial xcode projects and build settings, but it is likely smart enough to handle simpler cases.
2) you could create some scripts to accomplish what you're after. it wouldn't be terrible if you already have a project which builds out everything using common build settings. doing this manually is a pain, and is usually not a good use of time in larger projects if you are not using a high level of automation.
The goal of IDEs is increase productivity. They do a great job at that. Refactoring, navigation, inline documentation, auto completion help increase productivity immensely.
But: Every tool is a weapon. The very same IDE helps to produce chunk code. Some IDE features are an invitation to produce bad code: code generation, code formatting tools, refactoring tools.
IDE overuse tends to isolate developers from the necessary details. It is a good thing that you can start working but at some point in your career you have to be able to figure out how to start a process. You can ignore this detail for some time, in the end they are important to write a working product (vs. bolted together stuff that works 90% of the time).
How do you encourage positive behavior of other developers working with an IDE? This is a question as old as copy and paste.
To get the right impression: developers have to have the maximum freedom to mobilize their maximum creativity and motivation. They may use IDEs and all the related tools as they see fit. Nobody should impose draconian measures on them. I don't want to demotivate and force someone to do something. Good behavior has to be encouraged. It has to itch little a bit if you do the wrong thing. In the same line as the SO "accept rate" metric (and reputation). You can ignore it but life is better if you follow the rules.
(The solution should work in a given setting. You can ignore reviews, changing the staffing or more education as potential solutions.)
Train your IDE, instead of being trained by it.
Set up code formatting the way you (or your team) wants it. Heck, even disable it in cases where it makes sense. I've never seen an IDE align something like this with a sensible combination of tabs and spaces (where \t is obviously the tab character):
{
\tcout << "Hello "
\t << (some + long + expression +
\t to_produce_the_word(world))
\t << endl;
}
In languages like Java, you cannot avoid boilerplate. The best option you have is to check generated code, ensuring that it is the same as what you'd have written by hand. Modify it as necessary. Configure your IDE to generate the exact code that you need, if possible. Eclipse is pretty good at this.
Know what's going on under the hood.
Know that your IDE is actually invoking the compiler. Have some insight into the flags that it passes. Be able to invoke the compiler from the command line.
Know about the runtime system. Be aware of the flags that are used or needed to launch your program. Be able to launch the program from a command line.
I think before anyone uses a RAD tool of any type they should be able to write the application from scratch (scratch being wiring together the framework components) in notepad potentially on a computer that is 10 years older than current technology :P. Not knowing the ins and outs of a paradigm/framework leads to bad code from novice developers who only learn things at a mile high view of the platforms they develop for. Perhaps they should do this in a few technologies -- i.e., GTK programming is completely different to MVC which is then also different to SWING and .NET.
I think the end result should be a developer that thinks of the finer details of a problem before they jump to thinking of how they will write an interface to it in a specific RAD environment.
its an open ended question, but...
We have a Eclipse format file that everyone shares, so that we all format the code in the same manor. (Except the one lone InteliJ guy we have).
Everyone shares a dictionary file. It helps to remove all the red lines from the code. Making it look cleaner and more readable.
I run EMMA over the code to find out who isn't testing their code, and then moan at them.
The main problems we face is that most of the team don't know all the features/power of the IDE (eclipse). The didn't know about CTRL + O (twice), or auto code gen. All I can do as a 'hot key wizard' is keep sharing my knowledge with them to help them become more productive.
I look forward to the day when my problem is that they auto gen as much as possible.
Rather than me finding bugs where the wrong value is returned from a getter method due to a typo.
Attempt development (at least occasionally) using only a text editor and launching the compilation, testing, etc. from the command line.
Typing the commands will get tedious very quickly so create scripts or (even better) learn rake, ant, msbuild.
If the IDE does code generation for you and that code generation is really important (such as generating classes from xsd or proxy classes from wsdl), try to find out how to run the code generation from the command line - then hook the code generation into a build (so you'll never be tempted to edit the generated code).
The idea of autoformatting code is great but it usually just turns your code into a mess. If you have less code, minor formatting inconsistencies are just not a big deal.
Adding code quality tools into your build - style checks, class and method sizes, complexity, code duplication, test coverage, etc (complexian, simian, flog, flay, ndepend, ncover, etc.) will discourage IDE generated code.