Cory O'Daniel – These are just words Software development, thoughts, and randomness

7Jul/100

Testing if something is ‘true’ to all objects in an array/collection in ruby

Maybe there is something that does this already. I didnt know, so I whipped it together really quick. Its an extension to the array class that lets you know if something is 'true' to all objects in the array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Array
 
  def all_true?(&block)
    t_ref = true  
 
    if block_given?
      self.each do |_val_|
        t_ref &= !!(yield(_val_))
      end
    else
      self.each do |_val_|
        t_ref &= !!(_val_)
      end
    end
 
    t_ref
  end
 
end

You can use / test it like so:

1
2
3
4
5
6
[ true, true, true ].all_true?  #=> true
[ true, true, false ].all_true?  #=> false
 
# Want to run some other non boolean logic on it?
[ 1, 2, 3, 4, 5].all_true?{ |val| val.integer? } #=> true
[ 1, 'a', 3, 4, 6].all_true?{ |val| val.integer? } #=> false

Yeah, I just need to know is shits the same across the whole collection of active record objects sometimes. Now I can do it, go data.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

14Jun/100

Testing 404/500, Error Pages with Webrat visit method

This is a super simple snippet, and maybe there is something built into webrat, but I didn't find it. I needed to test for 404 pages in some of my tests (I was writing tests that made sure a page didnt show for disabled content). Purposely getting 404's can be annoying though since webrat opens up the 404 page in your default browser. There is a variable available in Webrat's configuration that you can use to temporarily disable this functionality. I wrapped it in the following method:

1
2
3
4
5
  def visit_but_dont_open(url)
    Webrat.configuration.instance_variable_set("@open_error_files", false)
    visit url
    Webrat.configuration.instance_variable_set("@open_error_files", true)
  end

Throw that in your test_helper and you can start doing:

1
2
visit_but_dont_open "Http://example.com/page/that/doesnt/exist"
assert !response.ok?

Yay, 404.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

Tagged as: , , No Comments
7May/100

Ruby 1.9 Date#strftime adds a space on %b

So, I had a spec failing in my integration suite and I couldn't figure out what the hell it was - EVERYTHING LOOKED LEGIT. I even logged into the site, and visually verified it. Whats the dilly?

I upgraded to ruby 1.9 from ruby 1.8 and apparently, when doing strftime on date, you get a free whitespace character with "%b"

1
2
3
# Ruby 1.8
irb(main):006:0> Date.today.strftime("%b %e, %Y")
=> "May 7, 2010"
1
2
irb(main):007:0> Date.today.strftime("%b %e, %Y")
=> "May  7, 2010" # TWO SPACES

Super dumb - wasted a good 10 minutes of my day because I could see the diff between:

1
2
"May  7, 2010"
"May 7, 2010"

In the middle of a web page full of other content.

Why the freebee space character on the %b? Dunno. I just smashed my stftime statement together and my specs are rolling.

1
Date.today.strftime("%b%e, %Y")

Uh, yeah - this is my bug report.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

17Apr/100

Padrino, Compass, and Sass – Working happily via Ian Serlin

My cohort, Ian Serlin, discovered this. In a project we are working on we could get Compass to play well with PadrinoRb. It seems like the #sass method doesn't care about the options being passed to it, and we kept getting stack traces rendered into our CSS files. The stack trace was ruby looking for - and failing to find compass/reset.css.

This is the code that DOESN'T work (padrino 0.9.10, compass 0.8.17, sinatra 1.0).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  configure do
    register SassInitializer #The Rack Sass reloader...
 
    Compass.configuration do |config|
      config.project_path = File.dirname(__FILE__)
      config.sass_dir = "stylesheets"
      config.project_type = :stand_alone
      config.http_path = "/"
      config.css_dir = "stylesheets"
      config.images_dir = "images"
      config.output_style = :compressed
    end
  end   
  get '/stylesheets/:file.css' do
    content_type 'text/css', :charset => 'utf-8'
    # This is the doc on how to give Sass some more load paths to find the compass  files. 
    #   it doesnt work :P and for that matter, neither does:
    # sass :file, Compass.sass_engine_options
    # or the set :sass, whatever_hash_here
    sass :file, :sass => Compass.sass_engine_options
  end

Our solution was to force Sass options and Compass options to merge...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  configure do
    register SassInitializer
 
    Compass.configuration do |config|
      config.project_path = File.dirname(__FILE__)
      config.sass_dir = "stylesheets"
      config.project_type = :stand_alone
      config.http_path = "/"
      config.css_dir = "stylesheets"
      config.images_dir = "images"
      config.output_style = :compressed
    end
 
    Sass::Plugin.options.merge!(Compass.sass_engine_options)
  end
 
  get '/stylesheets/:file.css' do
    content_type 'text/css', :charset => 'utf-8'
    sass :file
  end

Yay, magic spells - it works. You can check out more ian magic spells at ianserlin.com.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

5Mar/102

Attaching local or remote files to Paperclip and Milton Models in Rails (Mocking content_type and original_filename in a Tempfile)

I was working on a project today where I needed to import some data from MySpace accounts (yeah, MySpace), which included importing the users profile image. In the controller that did the importing I was using OpenURI to retrieve the image and then turn it into a Tempfile to be attached the the model, like so:

1
2
3
4
5
6
7
def import
#...snip
  tempfile = Tempfile.new( my_filename)
  tempfile.write open( image_url ).read
  @imported_user.images.create(:file => tempfile)
#...snip
end

This doesn't work. It blows up missing one of two methods:

  1. #original_filename
  2. #content_type

If you inspect a normal file upload in Rails which has these methods, you'll find that is just a regular old Tempfile. But it has the methods! If you create a Tempfile manually, it won't have the methods. That's because Rails magics them on. I am not sure why they don't create a subclass like Rails::Tempfile that contains these methods and just use that. I guess its because OOP is retarded (sarcasm).

So, I wrote a little subclass that will take a file path, and quack like the magic'd rails Tempfiles you get from an upload so you can attach local files to models or even remote files.

This works pretty straightforward and I'm currently using it in production. It won't work on windows systems because the dependency on the 'file' binary. Also, some linux systems are missing this library by default, so make sure you yum|dpkg|apt|port or whatever to get it installed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
require 'open-uri'
require 'digest/sha1'
 
class RemoteFile < ::Tempfile
 
  def initialize(path, tmpdir = Dir::tmpdir)
    @original_filename  = File.basename(path)
    @remote_path        = path
 
    super Digest::SHA1.hexdigest(path), tmpdir
    fetch
  end
 
  def fetch
    string_io = OpenURI.send(:open, @remote_path)
    self.write string_io.read
    self.rewind
    self
  end
 
  def original_filename
    @original_filename
  end
 
  def content_type
    mime = `file --mime -br #{self.path}`.strip
    mime = mime.gsub(/^.*: */,"")
    mime = mime.gsub(/;.*$/,"")
    mime = mime.gsub(/,.*$/,"")
    mime
  end
end

Usage is pretty simple:

1
2
3
remote_file = RemoteFile.new("http://www.google.com/intl/en_ALL/images/logo.gif")
remote_file.original_filename #=> logo.gif
remote_file.content_type #= image/gif

Using it in your controller:

1
2
3
4
5
def import
  #...snip
  @imported_user.images.create(:file => RemoteFile.new( url_to_image ))
  #...snip
end

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

25Feb/101

A ruby wrapper for Google AjaxLibs (jquery, jquery ui, mootools, prototype, swfobject, etc) [Lazy GoogleJsApi Wrapper]

I like using the Google AjaxLibs API. Its cool to not host files when I don't have to, especially ones I know a user has already probably cached from Google anyway (even though Google Page speed busts my balls about too many DNS lookups :P ).

I do on the other hand hate watching in the bottom of my browser "Waiting for google.com" when using the standard Javascript API for loading the Libraries like so:

1
2
3
4
<script type="text/javascript" src="http://www.google.com/jsapi?key=INSERT-YOUR-KEY"></script>
<script type="text/javascript">
 google.load("jquery", "1.4.2");
</script>

And you don't have to wait, you can totally do something like:

1
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

Which is why I wrote this little ruby wrapper. Its nothing special. It just encapsulates all the URLs for the libraries and their versions to allow you to not remember the URL and not have to go looking for the documentation when you start a new app or just need an additional library.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# Docs: http://code.google.com/apis/ajaxlibs/documentation/index.html
#
class GoogleJsApi
  BaseURL = "http://ajax.googleapis.com/ajax/libs".freeze
 
  Libraries = { 
    "jquery" => {
      :versions => %w(1.2.3 1.2.6 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2),
      :compressed_url => "/jquery/%s/jquery.min.js",
      :uncompressed_url => "/jquery/%s/jquery.js"
    },
    "jqueryui" => {
      :versions => %w(1.5.2 1.5.3 1.6 1.7.0 1.7.1 1.7.2),
      :compressed_url   => "/jqueryui/%s/jquery-ui.min.js",
      :uncompressed_url => "/jqueryui/%s/jquery-ui.js"
    },
    "prototype" => {
      :versions => %w(1.6.0.2 1.6.0.3 1.6.1.0),
      :compressed_url   => "",
      :uncompressed_url => "/prototype/%s/prototype.js"
    },
    "scriptaculous" => {
      :versions => %w(1.8.1 1.8.2 1.8.3),
      :compressed_url   => "",
      :uncompressed_url => "/scriptaculous/%s/scriptaculous.js"
    },
    "mootools" => {
      :versions => %w(1.1.1 1.1.2 1.2.1 1.2.2 1.2.3 1.2.4),
      :compressed_url => "/mootools/%s/mootools-yui-compressed.js",
      :uncompressed_url => "/mootools/%s/mootools.js"
    },
    "dojo" => {
      :versions => %w(1.1.1 1.2.0 1.2.3 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1),
      :compressed_url => "/dojo/%s/dojo/dojo.xd.js",
      :uncompressed_url => "/dojo/%s/dojo/dojo.xd.js.uncompressed.js"
    },
    "swfobject" => {
      :versions => %w(2.1 2.2),
      :compressed_url   => "/swfobject/%s/swfobject.js",
      :uncompressed_url => "/swfobject/%s/swfobject_src.js"
    },
    "yui" => {
      :versions => %w(2.6.0 2.7.0 2.8.0r4),
      :compressed_url   => "/yui/%s/build/yuiloader/yuiloader-min.js",
      :uncompressed_url => "/yui/%s/build/yuiloader/yuiloader.js"
    },
    "ext-core" => {
      :versions => %w(3.0.0 3.1.0),
      :compressed_url   => "/ext-core/%s/ext-core.js",
      :uncompressed_url => "/ext-core/%s/ext-core-debug.js"
    },
    "chrome-frame" => {
      :versions => %w(1.0.0 1.0.1 1.0.2),
      :compressed_url   => "/chrome-frame/%s/CFInstall.min.js",
      :uncompressed_url => "/chrome-frame/%s/CFInstall.js"
    } 
  }.freeze
 
  class << self
    def include(name, version=nil, compressed=true, validate_version=true)
      name = name.to_s
      if lib = GoogleJsApi::Libraries[name]
        version ||= lib[:versions].last
 
        if validate_version && lib[:versions].include?(version)
          GoogleJsApi.url_for(name, version, compressed)
        elsif !validate_version
          GoogleJsApi.url_for(name, version, compressed)
        else
          raise Exception, "Invalid version (#{version}) for #{name}"
        end
      else
        raise Exception, "Unknown Google Javascript Library"
      end
    end
 
    def version_info
      tmp_version = {}
      GoogleJsApi::Libraries.each do |k,v|
        tmp_version[ k ] = v[:versions]
      end
      tmp_version
    end
 
    protected
    def url_for(name, version, compressed)
      GoogleJsApi::BaseURL +
      GoogleJsApi::Libraries[ name ][ compressed ? :compressed_url : :uncompressed_url ] % version
    end
  end
 
end

Here are some tests for it if you are interested in how/if it works:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
require 'pp'
 
pp GoogleJsApi.version_info
 
# Include the newest version of a library
puts GoogleJsApi.include('jquery')
 
# Include a specific version of a library
puts GoogleJsApi.include "chrome-frame", "1.0.0"
 
# Include a specific version of a library uncompressed
puts GoogleJsApi.include "chrome-frame", "1.0.0", false
 
# Include a specific version of a library w/o validating the version; useful if this goes out of date :P
puts GoogleJsApi.include "jquery", "NOT_A_VERSION", false, false
 
begin
  puts GoogleJsApi.include :jqueryui, "1.0"
rescue Exception => e
  puts "This should blow up..."
  puts e.message
end

If you want to use it in your Rails or Merb app you can do:

1
2
3
4
5
# Rails
require 'google_js_api' #or whatever you named the file when you dropped it in lib
 
# In your application layout or whatever
javascript_include_tag GoogleJsApi.include(:jquery, "1.4.0")
1
2
3
4
5
# Merb
require 'google_js_api' #or whatever you named the file when you dropped it in lib
 
#in your application layout or where ever
require_js GoogleJsApi.include(:swfobject)

Its simple, its lazy. I like it.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

11Feb/100

Lower ACL Permissions on Amazon S3 items with ruby

I recently had to change a bunch of permissions on some items on S3. Unfortunately the items were mixed in with items that I didn't want to change the permissions on and the file names are all kinda jumbled, so I couldn't pinpoint what I needed to change by eyeballing the file names.

So I wrote a little ruby method to go in and change something given a key and bucket name.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require 'aws/s3'
 
AWS::S3::Base.establish_connection!(
  :access_key_id     => "YOUR_ACCESS_KEY",
  :secret_access_key => "YOUR_SECRET_KEY"
)
 
include AWS::S3
def s3_set_public_read(key, bucket)
  puts "Processing: #{key}"  
 
  policy = S3Object.acl(key, bucket)
  policy.grants << ACL::Grant.grant(:public_read)
  policy.grants << ACL::Grant.grant(:public_read_acp)
  S3Object.acl(key, bucket, policy)      
end

Now I can just run a loop of ActiveRecord objects around that method and convert them all to public read.

If you want a GUI tool for managing S3 stuff, I totally recommend S3Hub. Its a really sexy tool for managing S3.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

Tagged as: , , No Comments
10Feb/101

Expiring rails fragement caches using an expires time instead of a sweeper (expires_in) – (a ‘duh’ post)

So, I'm setting up fragment caching for some stuff, and I honestly don't care about setting up an observer to sweep some stuff. I just want to cache this one slow fragment for like 5 minutes. I've seen these tutorials all over the web that shows people using the expires_in setting to auto-expire cache like so:

1
Rails.cache.write('test_key', 'test_value', :expires_in => 5.minutes)

That's great and all, but how the hell do I use it for a Page, Action or Fragment cache? Well you just pass the same :expires_in param and yay it works as long as its a mem_cache_store (although, I did see a hackaroo for file_store)

Even the Rails Guide on caching mentions 'expires_in' but doesn't show how to use it.

1
2
3
class StupidController < ApplicationController
  caches_page :whatever, :expires_in => 5.minutes
end

What really got me was when I was trying to use it with a fragment cache. I tried this and it didn't work:

1
- cache(:action => 'home', :action_suffix => 'advertisements', :expires_in => 10.minutes) do

Why? Well, the cache method takes two hashes, and if you leave off the curly braces, that expires_in ends up in the first one, which is used for the name... To roll it right do:

1
- cache({:action => 'home', :action_suffix => 'advertisements'}, :expires_in => 10.minutes) do

Duh, the more you know.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

Tagged as: , , , 1 Comment
10Feb/100

A Rails rake file for compressing your Javascript with YUI

Here is a quick rake file I threw together to use with my Ruby YUI 2.0 (I-refuse-to-make-a-gem-
edition).

This of course should be used with the Ruby YUI Compressor I posted about the other day.

This script will tar/gzip all of your javascripts just incase something stupid happens. So you have a little safety net.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
require 'fileutils'
require 'pathname'
 
namespace :js do
  desc <<-INFO
Output Compressed JavaScript to STDOUT; 
  COMPRESS=ALL to compress all Javascript files that DONT contain ".min." 
INFO
 
  task :yui => :environment do
    targz()
    if ENV['COMPRESS'] == 'ALL'
      Dir[Rails.root.to_s / :public / :javascripts / '**/*.js'].each do |javascript|
        next if javascript =~ /\.min\./
 
        compress(javascript)
      end
    else
      if File.exist?(Rails.root + "config/yui.yml")
        javascripts = YAML.load(File.open("config/yui.yml").read)["javascripts"]
 
        if !javascripts.blank?
          javascripts.each {|script| compress(Rails.root + "public/javascripts" + script)}
        else
          raise Exception, "No javascript files in config/yui.yml" 
        end
      else
        raise Exception, "config/yui.yml Not Found; Do rake js:generate to create one or COMPRESS=ALL to run without a config file"
      end
    end
  end
 
  desc "Generate YUI Compressor Config file"
  task :generate => :environment do
    config_path = Rails.root + "config/yui.yml"
    File.open(config_path, "w+") do |f|
      f.puts <<-CONFIG
---
javascripts:
  - "application.js"
  - "jquery.js"
CONFIG
      puts config_path
    end
  end
 
  def targz()
    tgz_file = "#{Time.now.to_i}.javascripts.tgz"
    `cd #{Rails.root + "public"}; tar -zcf #{tgz_file} javascripts/`
    puts "Backed up assets to: #{tgz_file}"
  end
 
  def compress(path)
    puts "Compressing #{path}"
    file_handle = File.open(path)
    compressed_output = YUI.compress_safe file_handle
    file_handle.close
 
    #overwrite the file
    File.open(path, "w+") { |file| file.puts compressed_output }
  end
 
end

Wanna use it?
1. Drop it in your lib/tasks folder or wherever your Rakefile looks

You can compress 'everything' or specific files.

If you want to only compress specific Javascript files do:

1
2
3
rake js:generate 
# Edit your config/yui.yml file
rake js:yui

If you want to compress "everything" (It actually won't compress files that contain ".min.". You can remove the regexp's if you don't like it.)

1
rake js:yui COMPRESS=ALL

Yay, now your raking it in (Pun harhar) w/ your web2.0 yui compressed rails app. Woot woot.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

Tagged as: , , , No Comments
8Feb/101

Cory’s Ruby YUI Compressor v 2.0 Simpler, shorter.

So, a while ago I write a Ruby YUI Compressor Wrapper which is still available and works great (although it could use a newer jar file) as far as I know from Mandula's Blog. Some other guy also wrote one that pretty much had the same functionality as my gem. He must have hated it or something, I dunno. Even another guy wrote a wrapper for Closure Compiler if thats your bag.

Anywho, on a new project I'm working on *I just need a inline YUI compressor* and I dont give a damn about anything else like bundling, globbing or whatever. So I ended up throwing together this little (~50 lines less comments) Ruby YUI Compressor to do my dirty work.

I won't make it a gem probably, because if I do someone will just make a ruby-yui-simpler-also gem and put it on digg and get a bigger following :P (</sarcasm>)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
require 'open3'
require 'stringio'
 
class YUI
  include Open3 
  JAR_PATH = File.join(File.dirname(__FILE__),'yuicompressor-2.4.2.jar')
 
  class << self
    # @param io [String|File]
    # @param options [Hash] - See YUI.cli
    # @returns String
    #
    def compress(io, options = {})
      options[:type]    ||= :js
      options[:charset] ||= "utf-8"
 
      stdin, stdout, stderr = Open3.popen3( YUI.cli(options) )
      stdin.puts streamify(io).read
      stdin.close
 
      my_stderr = stderr.read
      my_stdout = stdout.read
 
      # if compression failed, just output original IO
      if my_stderr.empty?
        return my_stdout
      else
        raise Exception, my_stderr
      end
    end
 
    # If any exceptions are raised, the original string will be
    #   returned incase you are compressing stuff during a deploy
    #   and _just_dont_care_
    def compress_safe(io, options={})
      YUI.compress(io, options)
    rescue Exception => ex
      puts ex.message
      return streamify(io).read      
    end
 
    # Sets up the command line options
    # @param options [Hash]
    #   :jar_path         - [String] Path to the jar file, default "./yuicompress-2.4.2.jar"
    #   :charset          - [String] default 'utf-8'
    #   :type             - [Symbol] Options: js/css, default :js
    #   :line_break       - [Fixnum] Column to add line break at
    #   
    #   if the type of compression is JS, then additional options:
    #     :nomunge        - [Boolean] do not obfuscate
    #     :preserve_semi  - [Boolean] preserve all semicolons
    #     :disable_opt    - [Boolean] Disable all micro optimizations
    # 
    # @returns String
    #
    def cli(options)
      _cmd = ["java -jar #{options[:jar_path] || JAR_PATH}"]
      _cmd << "--type #{options[:type]}"
      _cmd << "--charset #{options[:charset]}" if options[:charset]
      _cmd << "--charset #{options[:line_break]}" if options[:line_break]
 
      if options[:type] == :js  
        _cmd << "--nomunge" if options[:nomunge]
        _cmd << "--preserve-semi" if options[:preserve_semi]
        _cmd << "--disable-optimizations" if options[:disable_opt]
      end
 
      _cmd.join(' ') 
    end
 
    # If a file or a string, treat it like its a stream
    #
    # @param string_or_stream [File|String]
    # @return StringIO
    #
    def streamify(string_or_stream)
      if string_or_stream.respond_to?(:read)
        string_or_stream.rewind if string_or_stream.eof?
        string_or_stream
      else
        StringIO.new(string_or_stream)
      end
    end
 
  end #end class << self
 
end

Wanna use it?
1. Copy the code above, throw it in your lib folder or where ever
2. Download the YUI compressor JAR file and put it in the same directory.
3. Do something like the following...

1
2
3
YUI.compress("function weebleep(){var cool_variable= 3; return cool_variable;}") #=> "function weebleep(){var a=3;return a};"
YUI.compress(File.open( "public/javascripts/application.js")) #=> A bunch of compressed javascript
YUI.compress(File.open( "public/stylesheets/application.css"), {:type => :css}) #=> Compressed stylesheet

Other options include:
:jar_path - [String] Path to the jar file, default "./yuicompress-2.4.2.jar"
:charset - [String] default 'utf-8'
:type - [Symbol] Options: js/css, default :js
:line_break - [Fixnum] Column to add line break at

if the type of compression is JS, then additional options:
:nomunge - [Boolean] do not obfuscate
:preserve_semi - [Boolean] preserve all semicolons
:disable_opt - [Boolean] Disable all micro optimizations

Yay have a blast. Its another compression wrapper.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

Tagged as: , , 1 Comment