I move between two network locations every day with my laptop, and came up with this script to automatically assign the http_proxy environment variable based on my current network location. Add this line in to your .bash_profile and new terminal windows will pick up the proxy automatically:
export http_proxy=`networksetup -getwebproxy Wi-Fi | awk '{ if(NR == 1) enabled=$2; else if(NR == 2) server=$2; else if(NR == 3) port=$2;} END {if(enabled == "Yes") print "http://" server ":" port}'`
Broken up:
- use the networksetup tool to grab the proxy information
- store the enabled state, server and port
- if the proxy is enabled, output a formatted string (http://SERVER:PORT) otherwise nothing
Getting Ruby Debug working for Ruby 1.9.2 in RVM is thankfully pretty easy. Make sure you’ve switched to 1.9.2 using RVM and run:
gem install ruby-debug19 -- --with-ruby-include=~/.rvm/src/ruby-1.9.2-p0
This is assuming you have a clean install of 1.9.2. If you have an old version of Ruby Debug for 1.9 you want to remove, run:
gem uninstall columnize ruby_core_source linecache19 ruby-debug-base19 ruby-debug19
Just to show it’s possible. I’d love to see better solutions (and solutions that don’t require storing a binding before the point of call):
def equals(val) lambda {|other| other == val} end module Handler def method_missing(sym, *args) args.first.call(eval(sym.to_s, $root)) end end self.extend(Handler) a = 1 b = 2 $root = binding # example where a != b a equals b => false b = 1 $root = binding # example where a == b a equals b => true
Ruby provides four equality methods on objects: ==, ===, eql?, andequal?. By default, BasicObject and Object define all four to be equivalent, but it’s common to redefine their semantics for subclasses to support hashes (which includes sets) and Enumerable methods such asuniq (which actually uses a hash in the MRI implementation). In Impromptu (a lazy loading and component dependency system I’m developing, similar to the autoloading features in ActiveSupport) I have a class which represents folders containing source files. I use a set to track all folder instances to ensure a folder is only included once:
component 'core' do folder 'src' end
component 'extensions' do folder 'src' end
Impromptu::ComponentSet.folders.count => 1
Each folder object has a path attribute, and two folders with the same path should be considered the same folder. Ruby hashes call the hashmethod on an object to create an integer value used for table lookups. It may make sense to only overload the hash method for folders but we run into problems:
# overload the hash method on folders to be the hash of the path class Folder def hash self.path.hash end end # create two folders with the same path f1 = Folder.new f1.path = "src" f2 = Folder.new f2.path = "src" # attempt to add both folders s = Set.new s << f1 => #}> s << f2 => #, #}>
This clearly doesn’t work. Although the hash of the two folders will be the same (4270666928775410514), when the hash object is performing a lookup it detects a collision on the key and tries to determine if the two objects are equal. If not, it assumes both objects just happen to have the same hash value and (if we’re performing an insertion) will insert the second object. This is important because it’s perfectly reasonable for two objects to have the same hash value yet not be equal, but it’s not the behaviour we want. Hash uses the eql? method to determine equality, so we need to override that too:
class Folder def eql?(other) self.path == other.path end end s = Set.new s << f1 => #}> s << f2 => #}>
Which is the behaviour we were after. You could also override == and===, but never override equal? as Ruby uses this to determine object identity equality. It’s also important to never base the hash of an object on a mutable value, unless you are sure it’s what you want to do. The hash of an array is based on the values contained in the array, and this causes problems if the values change:
# the hashes of arrays with the same values are equivalent a1 = [1] a2 = [1] a1.hash == a2.hash => true # add an array to the hash h = {} h[a1] = 1 h[a1] => 1 # problems arise when the set of values contained in an array change a1 << 2 h[a1] => nil # even though the inspect string of the hash suggests everything is fine h => {[1, 2]=>1} # this happens because the hash value of a1 has changed, so lookups on # a1 occur in the wrong place. if we revert a1 to what it was before, # the hash table can find a1 again a1.delete(2) h[a1] => 1
JavaScript has (for better or worse) few structures that some procedural and OOP languages have, e.g Classes, Enumerations (Enums), etc. Some of this comes from its Functional programming roots, and some from its Prototype object model. All in all I personally feel it works really well, and is a nice break from more traditional programming. But sometimes an old school programming structure is called for.
In a web app I’m writing, we have objects that are sent verbatim over JSON from a Database record. One of the attributes is an integer field representing the ‘type’ of the record (limited to the values from an enum we fake using Tuples in Python). When it came time to create the edit screen for these objects, it was obvious it would be nice to represent the possible values of this attribute in an enum JS side as well.
To do this we took advantage of the arguments variable accessible from within functions. All JS functions can be called with as few or as many arguments as you want – any missing arguments are passed to the function as ‘undefined’; extra arguments are available through the arguments variable. Because functions are represented as Function objects which have a length property, you can easily retrieve the number of parameters to a function:
> fn = function(a,b) {} > a.length 2
We can use the arguments variable to create Enumerations very easily.
function Enumeration() { this.allItems = []; for(var i = 0; i < arguments.length; i++) { name = arguments[i]; this[name] = i; this[i] = name; this.allItems.push(name) } }
This constructor function can then be used like this:
> var types = new Enumeration('show', 'new', 'edit', 'create', 'update', 'destroy') > types[0] show > types['show'] 0 > types.allItems.each(function(item) {console.log(item)}) index show new edit create update destroy
The types object can be used as a lookup both through the Enumerations values (0-6) and the keys or names of the values (‘index’ – ‘destroy’). For easy iteration over the values of the Enumeration, the allItems property is an array of the values (we use this to construct a select tag for choosing between the different values).