- Yes you can have reasonably good text-shadows.
- But only on a solid color background.
- Yes you can fadeIn and fadeOut text.
- But only on a solid color background.
- Yes you can even fadeIn and fadeOut transparent PNGS.
- But only once you’ve applied a transparent background. Even then it looks a bit awful.
Css Margin and Padding Shorthand
Css provides short hand properties for margin and padding which let you define multiple properties at once. For example:-
1 2 3 4 5 6 7 8 9 10 |
|
There are four variations of the shorthand property. You can specify 1, 2, 3 or 4 values, which are applied to the top, bottom, left and right margins. The problem that I had was trying to determine which value is applied to which side, especially if there are 2 or 3 values. There is an easy way to remember however.
Start at the top and go clockwise. If you run out of values, use the value already set for that axis.
So for example…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
How Rails, Nginx and X-Accel-Redirect Work Together
TL;DR - To use X-Accel-Redirect to serve static files from e.g /mnt/filestorage using send_file, put this in your nginx server configuration.
1 2 3 4 5 6 |
|
The need for X-Accel-Redirect (and it’s sibling X-Sendfile) comes from two distinct requirements
- The need to deliver large files.
- The need for those files to not be available to the public.
Here we are going to see how to set up X-Accel-Redirect and Rails. This is a bit complex so I’m going to run through a specific example of downloading a file. Along the way we’ll see the configuration, code and HTTP headers that are used. This assumes you already have Rails and Nginx installed and working.
1. Browser makes a request for a file
1 2 |
|
2. Nginx receives this request. It adds on a header with configuration data that will be required by rails.
1 2 3 4 5 6 |
|
3. Nginx passes the request onto Rails and it invokes the relevant controller.
4. The controller makes its authorization checks and calls send_file. Use the absolute path to the file.
1 2 |
|
5. Rails (Rack to be precise) then decides what to with the file. We need to tell rails to use X-Accel-Redirect in its configuration as shown below. Instead of using the file as the body of the request, it will add a header to the response. It uses the X-Accel-Mapping that nginx added earlier to change the file path.
1 2 3 4 5 6 7 8 9 10 |
|
6. Nginx receives this header from rails and interprets it. It finds the location directive and reverses the changes to the path that rails made in step 5.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
7. Browser receives the file as if it was a normal download.
Also, if you have compiled passenger into nginx, remember to use passenger_set_cgi_param instead of proxy_set_header
Software Versions used
- Rails 3.0.7
- Passenger 3.0.5
- Nginx 0.8.54
- on Ubuntu 10.04.2 LTS
Resources
Adding Headers to Requests Using Nginx and Passenger
TL;DR If you have compiled Passenger into Nginx, use passenger_set_cgi_param
instead of proxy_set_header
to set HTTP headers required by the rails process.
There are two ways of using Passenger and Nginx together. The first is when the two are compiled into one daemon that creates many processes as required. The second is using Nginx as a proxy in front of Passenger/Apache/Nginx processes running either on the same machine or on a different server altogether.
When using Nginx as a proxy, it can be configured to add or redefine http headers in the request. This is done using the proxy_set_header
directive.
1
|
|
If you have compiled Passenger into Nginx, the above configuration will have no effect. This is because the request is not considered to be proxied by Nginx. To have the same effect you need to use the passenger_set_cgi_param
directive.
1
|
|
Notice that the header name is all upper case, and has HTTP_
prefixed.
Differences Between PHP Arrays and Ruby Hashes
We've looked at the differences between Ruby and PHP arrays before. Now lets compare PHP arrays and Ruby hashes. They should be similar as all PHP arrays are implemented as hashes. There is however a crucial difference that can trip you up if you are switching from one language to another.
Referencing an index that hasn't been set is an error in PHP, but not in Ruby.
In PHP, retrieving a value for an index that you haven't used is a warning. Although warnings can be turned off it is best practice to develop with them turned on.
1 2 3 4 5 6 7 8 9 10 11 |
|
In Ruby you can set a default value for all keys that have not set a value. By default this value is nil.
1 2 3 4 5 6 7 8 9 10 |
|
Ruby hashes are unordered (up to version 1.8). PHP arrays have an internal order seperate from their index.
When you loop through a PHP array, the values will be returned in the order they were added.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
In Ruby 1.8 hashes are unordered, they could be retreived in any order that ruby decides is best. Ruby 1.9 changes this so that it works in the same way as the PHP example above.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Is there anything that has been missed? Add a comment below.
Major Differences Between PHP and Ruby Arrays
PHP has a single array type, where as Ruby has Array and Hash, which covers the same functionality. In this article i'll go though the three major logical differences between PHPs array type and Rubys Array class. We compare PHP arrays and Ruby Hashes in separate post.
Firstly,
PHP arrays have an internal order separate from their index.
Lets look at a simple example. In php the order you insert values into an array determines the order that php will return them using foreach.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Ruby on the other hand uses the key or index of the array to determine the order, regardless of order in which the values are inserted.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Secondly,
Ruby arrays always start at 0 and end at the highest index. PHP arrays only contain the keys that have been entered.
In the example below, PHP will output the two array values that are set.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
In the ruby example, not only are the two values output, but an attempt is made to get the value from every index between 0 and the highest index set.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
This leads to another difference…
Referencing an array index that hasn't been set is an error in PHP, but not in Ruby.
The following code produces a PHP notice. Notices are a low severity error, and are usually turned off on production servers. However it is considered good practice to develop with notices turned on.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Ruby on the other hand does not consider this an error. It will return the nil value which is 'kind of' like PHPs null.
1 2 3 4 5 6 7 8 9 10 |
|
So what are your experiences switching between PHP and Ruby. Let me know in the comments below.
7 Habits of Highly Ineffective People
My Secret Santa decided to treat me to a copy of Stephen Covey’s The Seven Habits of Highly Effective People. Presumably because I’m ineffective in some way, which is completely true. Here then is my list of how to be a highly ineffective person.
- Social Networking. Check Twitter/Facebook every 5 minutes. Someone might upload a photo of you at any minute. You must know ASAP.
- MSN. Having personal conversations on MSN can sap anything from 10 minutes up to an hour or two from your day.
- Hangovers. Nothing keeps you alert like having a late night the night before. Especially if you are a "2 pint screamer" like myself.
- Wikiwalk. Do a Google search on how to open a file in ruby. An hour later your reading about the Boer War in South Africa. You have no idea how this happened.
- News feeds. Keeping up with the world and what is happening in your industry is important. Reading every article from the 200 feeds you are subscribed too isn’t.
- Coffee Time. Making a cup of tea/coffee is a great little stretch for you. To really be ineffective, make a cup for the rest of the office as well.
- Unread books. Buying books and not reading them is a surefire way to feel smart. I currently have The Passionate Programmer, Linchpin and the 7 habits book waiting to be read/finished.
Is there anything missing. Do you have a favourite time waster? Let everyone know with a comment.
The Best Feature of VIM Not in IDE’s
Insertion mode keyword completion
Ctrl-P and Ctrl-N in insert mode to search through the text to try and complete whatever variable name you are typing. I’ve never seen this in any other IDE and I really miss it. Code completion in IDE’s just isn’t the same.
Speak the Truth
Improper uses of Booleans causes headaches for people who are reviewing your code. Lets take a look at some good, and not so good uses.
Don’t be negative
1
|
|
Looks simple and readable right? Wrong. It's one step away from being misused.
1
|
|
Not not logged in. Double negatives are a gotcha in language and coding and should be avoided. Fortunately the solution is an easy one. Remove the negative prefix (such as not, doNot, dont) from the variable name.
1 2 3 |
|
Hide Literals
1
|
|
Is it really necessary to compare the variable to false? Imagine this conversation.
You are at Subway and they ask you
'Would you like your sandwich toasted?'
Would you reply with
'Toasted equals false'
Or
'Not Toasted'
Avoid comparing with a literal true or false. The correct way to express this is :-
1
|
|
A Boolean Flag?
1
|
|
$reportFlag is a little vague. In this case it is determining if an object is included in a report. So if $reportFlag is true, does that mean that the object is included or excluded? If you have to ask yourself the question then you have already failed and need to rethink what this variable should be called.
1
|
|
This is okay as long we are using the word ‘report’ as a verb. ‘If we report this then’ is how you would read this. Some people may not be able to make that leap so if you want to be more precise you could make it :-
1
|
|
Summary
So to sum up, these three things will go a long way to making your code readable.
- Remove the negative prefix (such as not, doNot, dont) from variable names.
- Avoid comparing with a literal true or false.
- Avoid vague terms like flag for Boolean values.
Consider these ideas when choosing
- Variable names
- Object properties
- Database field names
- Method or function parameter names
Anything Else?
Is there something i’ve missed? A hole you could drive a double-decker bus through? Leave a comment below.
Ctrl-A Delete
Usually a last resort. Often the best thing to do.