Code Monkey home page Code Monkey logo

sprockets's Introduction

Welcome to Rails

What's Rails?

Rails is a web-application framework that includes everything needed to create database-backed web applications according to the Model-View-Controller (MVC) pattern.

Understanding the MVC pattern is key to understanding Rails. MVC divides your application into three layers: Model, View, and Controller, each with a specific responsibility.

Model layer

The Model layer represents the domain model (such as Account, Product, Person, Post, etc.) and encapsulates the business logic specific to your application. In Rails, database-backed model classes are derived from ActiveRecord::Base. Active Record allows you to present the data from database rows as objects and embellish these data objects with business logic methods. Although most Rails models are backed by a database, models can also be ordinary Ruby classes, or Ruby classes that implement a set of interfaces as provided by the Active Model module.

View layer

The View layer is composed of "templates" that are responsible for providing appropriate representations of your application's resources. Templates can come in a variety of formats, but most view templates are HTML with embedded Ruby code (ERB files). Views are typically rendered to generate a controller response or to generate the body of an email. In Rails, View generation is handled by Action View.

Controller layer

The Controller layer is responsible for handling incoming HTTP requests and providing a suitable response. Usually, this means returning HTML, but Rails controllers can also generate XML, JSON, PDFs, mobile-specific views, and more. Controllers load and manipulate models, and render view templates in order to generate the appropriate HTTP response. In Rails, incoming requests are routed by Action Dispatch to an appropriate controller, and controller classes are derived from ActionController::Base. Action Dispatch and Action Controller are bundled together in Action Pack.

Frameworks and libraries

Active Record, Active Model, Action Pack, and Action View can each be used independently outside Rails.

In addition to that, Rails also comes with:

  • Action Mailer, a library to generate and send emails
  • Action Mailbox, a library to receive emails within a Rails application
  • Active Job, a framework for declaring jobs and making them run on a variety of queuing backends
  • Action Cable, a framework to integrate WebSockets with a Rails application
  • Active Storage, a library to attach cloud and local files to Rails applications
  • Action Text, a library to handle rich text content
  • Active Support, a collection of utility classes and standard library extensions that are useful for Rails, and may also be used independently outside Rails

Getting Started

  1. Install Rails at the command prompt if you haven't yet:

    $ gem install rails
  2. At the command prompt, create a new Rails application:

    $ rails new myapp

    where "myapp" is the application name.

  3. Change directory to myapp and start the web server:

    $ cd myapp
    $ bin/rails server

    Run with --help or -h for options.

  4. Go to http://localhost:3000 and you'll see the Rails bootscreen with your Rails and Ruby versions.

  5. Follow the guidelines to start developing your application. You may find the following resources handy:

Contributing

We encourage you to contribute to Ruby on Rails! Please check out the Contributing to Ruby on Rails guide for guidelines about how to proceed. Join us!

Trying to report a possible security vulnerability in Rails? Please check out our security policy for guidelines about how to proceed.

Everyone interacting in Rails and its sub-projects' codebases, issue trackers, chat rooms, and mailing lists is expected to follow the Rails code of conduct.

License

Ruby on Rails is released under the MIT License.

sprockets's People

Contributors

ahorek avatar amatsuda avatar andreis13 avatar bolandrm avatar byroot avatar deivid-rodriguez avatar dgraham avatar dhh avatar eileencodes avatar elia avatar eregon avatar erol avatar guilleiguaran avatar jeremy avatar josh avatar joshk avatar jrochkind avatar kaspth avatar lsylvester avatar lucasmazza avatar matthewd avatar michaelherold avatar modosc avatar prathamesh-sonpatki avatar rafaelfranca avatar schneems avatar sstephenson avatar tenderlove avatar twalpole avatar vipulnsward avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sprockets's Issues

sprockets returning nil

First of all, here's my code as a gist

Sprockets only returns nil, I've done this

 settings.assets.instance_exec(file_name,extention) do |file_name,extention|
    puts 'assets'
    puts @assets
    @assets[cache_key_for("#{file_name}#{extention}", {bundle: true})]
end

To see what files sprockets has and @assets is just {}

I know however that file name is being correctly passed becuase:

puts params[:captures].to_s # in my asset routes output
  #=> ["application", ".css"]
  #=> ["application", ".js"]

It also doesn't raise any errors.

I don't know what's wrong or how to fix this, what do I do?

Getting `NoMethodError: undefined method `+' for nil:NilClass` trying to compute an asset path

We're running a version of basecamp against rails master (including sprockets master) and a change since 92eb307 is raising an error trying to find an asset path.

I'm not sure the exact cause, but have traced it down to the following:

A metadata reducer for :sass_dependencies has recently been added here: https://github.com/rails/sprockets/blob/master/lib/sprockets.rb#L144

This reducer is called here when h[k] is nil: https://github.com/rails/sprockets/blob/master/lib/sprockets/bundle.rb#L55

I'm not sure really what this code is meant to be doing, so can't really tell what's going wrong. Happy to try and find any extra debug information or anything extra that will help. In case it's useful, here's more of the backtrace:

.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/bundle.rb:58:in `call'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/bundle.rb:58:in `block (2 levels) in process_bundle_reducers'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/bundle.rb:54:in `each'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/bundle.rb:54:in `block in process_bundle_reducers'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/bundle.rb:53:in `each'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/bundle.rb:53:in `reduce'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/bundle.rb:53:in `process_bundle_reducers'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/bundle.rb:37:in `call'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/processor_utils.rb:73:in `call_processor'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/processor_utils.rb:55:in `block in call_processors'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/processor_utils.rb:54:in `reverse_each'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/processor_utils.rb:54:in `call_processors'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/loader.rb:100:in `load_asset_by_uri'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/loader.rb:40:in `block in load'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/loader.rb:167:in `fetch_asset_from_dependency_cache'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/loader.rb:33:in `load'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/cached_environment.rb:20:in `block in initialize'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/cached_environment.rb:47:in `yield'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/cached_environment.rb:47:in `load'
.bundle/gems/bundler/gems/sprockets-9c0d8d4f4a88/lib/sprockets/base.rb:63:in `find_asset'

erb is processed after `require`s?

I'm trying to dynamically require files on a certain directory (that's already added to the load path), doing this:

/*
<% Dir.glob(Rails.root.join('app', 'components', '*')) do |component_dir| %>
<% component = File.basename component_dir %>
 *= require <%=component%>/<%=component%>
<% end %>
*/

I was expecting erb to be processed before the actual require call, but I'm getting this error:
couldn't find file '<%=component%>/<%=component%>'

It seems like it's processing the erb after requiring the rest of the files.

Is that on purpose? If so is there a way to somehow dinamically require the files there?

This is on the context of a Rails engine, where I'd like to have one file on the engine that dinamically requires files in the application directory.
I can't use require_tree because that app/components directory is the one added on the path.

Sprockets 3.0.0.rc QA

I think I'm ready to call 3.0 done. I don't know of any blockers, so heres you chance to tell me!

Production apps running 3.0.0.beta.10 (will be rc1)

  • github.com
  • basecamp.com
  • rubygems.org

A few people mentioned they testing the Sprockets betas. Let me know if theres any other interesting apps.

/cc @jeremy @sstephenson @rafaelfranca @arthurnn

Not loading "index" templates

After upgrading to sprockets 3.0, require will no longer find or load templates named index.jst.eco

Is this intentional?

Sprockets does not work well in multi-process environments like Solano CI

According to Solano CI, a continuous integration test service:

Many Rails applications use hardcoded paths by default, often relative to “/tmp” or Rails.root. Test threads in Solano CI may not have access to /tmp, and two processes writing to the same file will probably run into trouble.

We have found this to be the case, as our team would sporadically get "ActionView::Template::Error: end of file" errors on Solano CI. The root cause of these errors is that Sprockets chooses a location for its FileStore cache that is not multi-process friendly.

We have locally patched version 2.12.3 like so and it has fixed these intermittent errors:

module Sprockets
  module Cache
    class FileStore
      def initialize(root)
        fore, aft = root.split('tmp')
        multiprocess_safe_location = File.join(Dir.tmpdir, aft)
        @root = Pathname.new(multiprocess_safe_location)
      end
    end
  end
end

I'd suggest tweaking Sprockets' behavior so it works well in multiprocess environments.

Performance regression while requiring lots of files

Hi guys,

I'm following rails/sprockets-rails#225 and I would like to share with you a performance regression I'm experiencing after moving from sprocket-rails 2.1.3 to 3.0 or master.

It turns out that the issue is not in sprocket-rails but rather in the underlying sprockets since most of the time is spent resolving asset paths (cc @eileencodes).

Here is what I'm seeing on my personal app (ruby-prof output):

Measure Mode: wall_time
Thread ID: 70253745167340
Fiber ID: 70253756137300
Total: 1.518107
Sort by: self_time

 %self      total      self      wait     child     calls  name
 19.84      0.302     0.301     0.000     0.000     1368   <Module::Marshal>#load_without_autoloading
  5.71      0.087     0.087     0.000     0.000      143   Zlib::Inflate#inflate
  4.60      0.070     0.070     0.000     0.000     1339   <Class::File>#utime
  4.22      0.074     0.064     0.000     0.010     1908   Sprockets::URIUtils#join_file_uri
  3.72      0.448     0.056     0.000     0.392     1339   Sprockets::EncodingUtils#unmarshaled_deflated
  3.58      0.054     0.054     0.000     0.000    21137   String#scan
  2.48      0.222     0.038     0.000     0.184    20937   Sprockets::Resolve#parse_path_extnames
  2.16      0.033     0.033     0.000     0.000     4095   <Class::File>#exist?
  2.03      0.031     0.031     0.000     0.000        2   SQLite3::Statement#step
  1.77      0.055     0.027     0.000     0.029    20939   Array#reverse_each
  1.75      0.048     0.027     0.000     0.021      302   Array#include?
  1.74      0.028     0.026     0.000     0.002     7471  *String#gsub
  1.63      0.025     0.025     0.000     0.000     1370   File#initialize
  1.46      0.022     0.022     0.000     0.000   120894   String#==
  1.42      0.052     0.022     0.000     0.031     1831   Sprockets::DigestUtils#digest
  1.38      0.021     0.021     0.000     0.000    21201   <Class::File>#basename
  1.32      0.020     0.020     0.000     0.000       20   <Class::Dir>#[]
  1.29      0.020     0.020     0.000     0.000     3203   Regexp#===
  1.28      0.161     0.019     0.000     0.141    20937   Sprockets::PathUtils#match_path_extname

screen shot 2015-08-01 at 13 41 11

And here is a small project reproducing the issue: redox/perf_regression_sprockets. In that application a page that took 20ms to be rendered using sprockets-rails 2.1.3 now takes 60ms with the latest master branch.

Any chance it could be related to the "compat" resolving layer? Let me know if I can help!

Absolute resolved file path slows pre-compilation between deploys in Sprockets 4.x

I was able to reproduce #59 for Sprockets 4 using master:

Compress javascript in main directory:

2.2.2  ~/documents/projects/tmp/test-move-3.2-8 (schneems/sprockets-4.x)
$ time bundle exec sprockets -I app/assets/javascripts/ -o __out/ --js-compressor=uglifier --cache ./__cache application

real  0m34.765s
user  0m24.621s
sys 0m12.214s

Confirm cache works in same dir:

2.2.2  ~/documents/projects/tmp/test-move-3.2-8 (schneems/sprockets-4.x)
$ time bundle exec sprockets -I app/assets/javascripts/ -o __out/ --js-compressor=uglifier --cache ./__cache application

real  0m1.794s
user  0m1.080s
sys 0m0.314s

Yup, move all the files

2.2.2  ~/documents/projects/tmp/test-move-3.2-8 (schneems/sprockets-4.x)
$ cd ..

2.2.2  ~/documents/projects/tmp
$ cp -R test-move-3.2-8/ test-move-4-1

2.2.2  ~/documents/projects/tmp
$ cd test-move-4-1/

Re run test, should be fast since files already there:

2.2.2  ~/documents/projects/tmp/test-move-4-1 (schneems/sprockets-4.x)
$ time bundle exec sprockets -I app/assets/javascripts/ -o __out/ --js-compressor=uglifier --cache ./__cache application

real  0m36.859s
user  0m25.891s
sys 0m13.270s

Ouch, that wasn't fast. Double check caching still works:

2.2.2  ~/documents/projects/tmp/test-move-4-1 (schneems/sprockets-4.x)
$ time bundle exec sprockets -I app/assets/javascripts/ -o __out/ --js-compressor=uglifier --cache ./__cache application

real  0m1.861s
user  0m1.119s
sys 0m0.327s

Getting error when including manifest.js in Sprockets 3.0

When I include a manifest.js, I get the following error:

Asset filtered out and will not be served: add Rails.application.config.assets.precompile += %w( application.css ) to config/initializers/assets.rb and restart your server

Did not see this in the upgrade guide and was wondering if this should be documented?

Thanks.

Usage of random() in a sass stylesheet breaks sprockets

Having just updated to sprockets 3.0.2, my rails app began to raise a Sprockets::VersionNotFound exception when evaluating stylesheet_link_tag('application').

Here's the complete error:

could not find specified id: file:///[...]/app/assets/stylesheets/application.scss?type=text/css&pipeline=self#4563a7b014631a51625729c3ac881b6d4bc10d5ee7b37f41c001461ad54a7a1a

I tried stepping through both sprockets and sprockets-rails and I traced it down to multiple consecutive calls to Sprockets::Loader.load. The first one creates a new Asset with a corresponding id. The second one tries to lookup the cached asset by id, but fails since the compiled stylesheet contains different random values and the ids don't match.

Now, I understand that using random() in a sass stylesheet is kind of unusual (we need a ton of randomized values to get some complex CSS animations to look natural and this was much easier than hardcoding them by hand). I also haven't tried simulating a deployment so I don't know if this happens in production too. I still believe that, even if the problem was unfixable without significantly altering the sprockets architecture, it would at least warrant some kind of warning or a more specific error message.

I can reproduce the bug easily, so let me know if you need a minimal repo to test it.

ruby 1.9.3p194 (I know, our client's IT department doesn't want to update)
rails 4.2.1
sprockets 3.0.2
sprockets-rails 2.2.4

Babel modules roadmap

Currently Babel is switched to replace ES6 module declarations with CommonJS requires, whereas Sprockets does not provide a runtime to handle those requires.

Is there some roadmap as to how modules are going to be wired into Sprockets, or does it have to be handled by some module you have to BYO?

JavaScript asset not found if directory has extension (.js)

See original issues : rails/rails#18859 and sstephenson#706

Error is still present in sprockets 3.2.0

Problem is when the directory is named something.js (which is quite a common thing to do in the js community)

So you'd want to require it like this :

//= require something.js

But you'd get the error below :

Sprockets::FileNotFound - couldn't find file 'something.js' with type 'application/javascript':

Ugly workaround : adding a second .js in the requirement seems to trick sprockets

//= require something.js.js

How to clear asset path cache in tests?

Hi,

Thanks for your work on this project! I'm working on improving the tests for react-rails (reactjs/react-rails#253).

A feature I want to test is that:

  • The gem provides a version of react.js
  • A user may drop another copy of react.js into /vendor/assets/javascripts and that one will be served

However, I'm running into this problem that after calling Rails.application.assets["react.js"] once, I can't make it return a new result, even if I add files to /vendor/assets/javascripts. It keeps serving the old file.

(In my case, it's a total bummer: one test needs real react.js, the other one needs to check a dropped-in copy. The different tests conflict with each other 😩 )

I've tried:

  • Clearing tmp/cache between tests (but the paths are preserved in Ruby memory)
  • Overriding Sprockets::Asset#fresh?(env), didn't seem to do the job
  • Calling protected method Sprockets::Environment#expire_index, but that's not present in recent Sprockets
  • Forcing a reload with ActionDispatch::Reloader.cleanup! && ActionDispatch::Reloader.prepare!

Do you have any suggestions for this kind of testing? Is there a good option that I have overlooked?

Thanks!

bundle/root pipeline to bootstrap module systems

Hi @josh,

in my endless quest with sprockets and opal I was going through the sprockets source and I think there's a chance to make module systems happy, or at least opal's require system happy.

The problem is bootstrapping the root file, which is the one that is usually linked with javascript_include_tag. The obvious solution would be to inject the bootstrapping code in a bundle processor as it's called (if I understood correctly) on the root file with all the required assets available.

The problem is it's not called if the debug bit is on (aka the self processor).

So, if my assumptions are correct it should be possible to change the javascript_include_tag helper to pass through the self pipeline all assets but the root, and add an ad-hoc "self_root" pipeline for it.

The current opal-rails implementation overloads javascript_include_tag injecting the bootstrapping code in a <script> tag if debug is on. Here's an example

What I envision is to have the last of the ?body=1 files be called as something like ?body=1&bundle=1.

From:

<script src="/assets/scroll_up_link-05ca5d05788cc62265bbc4508d80d33f.js?body=1"></script>
<script src="/assets/models/cart-219dd7a6950beb74573b3a106e74970b.js?body=1"></script>
<script src="/assets/inner-d59fa604d4efa67f6b3b204d4529f323.js?body=1"></script>
<script src="/assets/application-6237095f72d7abc6b6df9e5d5284aece.js?body=1"></script>
<script>Opal.load("application")</script>

To:

<script src="/assets/scroll_up_link-05ca5d05788cc62265bbc4508d80d33f.js?body=1"></script>
<script src="/assets/models/cart-219dd7a6950beb74573b3a106e74970b.js?body=1"></script>
<script src="/assets/inner-d59fa604d4efa67f6b3b204d4529f323.js?body=1"></script>
<script src="/assets/application-6237095f72d7abc6b6df9e5d5284aece.js?body=1&bundle=1"></script>

sprockets-es6 gem

Tried looking for sprockets-es6 gem and I don't see it anymore. Was this merged into sprockets? I don't see it in the changelog. I just see: Support circular dependencies. For parity with ES6 modules.

Create stub with regular expression

I made another issue for sprockets-rails but I think it belongs here instead.

I have an angular front end and I want to include all my unit test files in my project assets(in each feature module). Currently I have to stub every test file that is included, but what would be more ideal is if I could pass in a regular expression and have stub remove all test files that end in _spec.coffee.

After looking at some of the code, it looks like here:

https://github.com/rails/sprockets/blob/master/lib/sprockets/directive_processor.rb#L243

could take an options parameter that would have stub or even a regular expression and check to make sure as it is recursively adding the files that they don't fall under the regular expression. Actually maybe the method that it is calling:

https://github.com/rails/sprockets/blob/master/lib/sprockets/directive_processor.rb#L349

then this

https://github.com/rails/sprockets/blob/master/lib/sprockets/directive_processor.rb#L361

and it looks like it already has an options parameter.

Maybe have it be:

//= require_tree ., stub: /.*_spec.coffee/

What do you think?

Thanks.

Get more engine extnames

Current computation of extnames losing some necessary extensions, for example .jst.eco.erb or .jst.ejs.erb. So if I add engine "skim" there is no .jst.skim.erb accessible extname. I think we need to add more engine available to use.

Uglifier compressor generates random variable names under 3.x

This one is a bit complex, but I'll try to provide as much detail as possible.

After upgrading from sprockets 2.12.4 to 3.0.3 (or 3.2.0) I get different digests for many of my JS files on different production machines. If I disable Uglifier compression in Rails config then the problem goes away and the digests are the same. With Uglifier enabled the differences look like this:

Instance 1

(function(){$(function(){var t,e,i,n,o,r,a,s,l;if

Instance 2

(function(){$(function(){var e,t,r,i,n,o,a,s,h;if

I have looked on the whole files and the only differences are in variable names and function parameter names.

The other relevant gems in my setup are:

    execjs (2.5.2)
    libv8 (3.16.14.11)
    therubyracer (0.12.2)
    uglifier (2.7.1)
    sprockets-rails (2.3.2)

Keeping all these gem versions constant and only changing sprockets version the problem is introduced somewhere between 2.12.4 and 3.0.3. It might be an issue of sprockets-rails though - maybe it doesn't handle sprockets 3.x well yet.

Don't know if it matters, but these JS files are added to sprockets like this:

# config/initializers/assets.rb

Rails.application.config.assets.precompile += Rails
  .root
  .join("app/assets/javascripts/page_scripts")
  .children(false)
  .map {|file|
    file = file.to_s
      .sub(/\.erb\z/, '')
      .sub(/\.coffee\z/, '')
    "page_scripts/#{file}"
  }

[4.2.1] index.scss not correctly linked

From @JohnDoe42 on May 3, 2015 20:28

  1. rails new ./ (in project folder)
  2. rails generate controller index
  3. rails generate controller indexx
  4. rails assets:precompile
  5. run server and open root folder in browser

Sourcecode:

<link rel="stylesheet" media="all" href="/assets/..self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="true" />
<link rel="stylesheet" media="all" href="/assets/indexx.self-e80e8f2318043e8af94dddc2adad5a4f09739a8ebb323b3ab31cd71d45fd9113.css?body=1" data-turbolinks-track="true" />
<link rel="stylesheet" media="all" href="/assets/application.self-d03a5518f45df77341bdbe6201ba3bfa547ebba8ed64f0ea56bfa5f96ea7c074.css?body=1" data-turbolinks-track="true" />

You will notice, that the "..self-.css" link will not work (403) except you remove one dot (".self-.css")

This only happens if I generate a controller named "index" - everything else works. Help appreciated - might be a layer 8 problem.

Bundle:

Using rake 10.4.2
Using i18n 0.7.0
Using json 1.8.2
Using minitest 5.6.1
Using thread_safe 0.3.5
Using tzinfo 1.2.2
Using activesupport 4.2.1
Using builder 3.2.2
Using erubis 2.7.0
Using mini_portile 0.6.2
Using nokogiri 1.6.6.2
Using rails-deprecated_sanitizer 1.0.3
Using rails-dom-testing 1.0.6
Using loofah 2.0.1
Using rails-html-sanitizer 1.0.2
Using actionview 4.2.1
Using rack 1.6.0
Using rack-test 0.6.3
Using actionpack 4.2.1
Using globalid 0.3.5
Using activejob 4.2.1
Using mime-types 2.5
Using mail 2.6.3
Using actionmailer 4.2.1
Using activemodel 4.2.1
Using arel 6.0.0
Using activerecord 4.2.1
Using debug_inspector 0.0.2
Using binding_of_caller 0.7.2
Using columnize 0.9.0
Using byebug 4.0.5
Using coffee-script-source 1.9.1.1
Using execjs 2.5.2
Using coffee-script 2.4.1
Using thor 0.19.1
Using railties 4.2.1
Using coffee-rails 4.1.0
Using multi_json 1.11.0
Using jbuilder 2.2.13
Using jquery-rails 4.0.3
Using bundler 1.9.4
Using sprockets 3.0.3
Using sprockets-rails 2.2.4
Using rails 4.2.1
Using rdoc 4.2.0
Using sass 3.4.13
Using tilt 1.4.1
Using sass-rails 5.0.3
Using sdoc 0.4.1
Using spring 1.3.5
Using sqlite3 1.3.10
Using turbolinks 2.5.3
Using uglifier 2.7.1
Using web-console 2.1.2
Bundle complete! 12 Gemfile dependencies, 54 gems now installed.
Bundled gems are installed into ./vendor/bundle.

Copied from original issue: rails/rails#20001

Memory leak?

Hi guys. I recently updated sprockets from 2.12.3 to 3.1.0 and sprockets-rails from 2.2.4 to 2.3.1 and I'm noticing a slow growing memory leak on Heroku after the change.

heroku metrics

My app is pretty large so I'm still trying to isolate the leak. Any thoughts on the best way to track this down?

Improving alias resolution

Issues around alias resolving have come up a few times, but we haven’t come up with a logically sound fix for the root cause.

Current Behavior

Sprockets currently supports two built-in path “alias” cases.

  1. Directory “index” files - If you attempt to resolve a directory and that directory contains an “index.whatever”, that “index” file will be chosen. This feature was model after node.js’s “index.js” convention.
  2. Bower “main” assets - Bower packages can declare a set of packages in their “main” property. That file is used if the bower package directory is required. This lets people require jquery when jquery.js is actually nested under bower_components/jquery/dist/jquery.js.

Issues

Static Manifest

In production environments only a static manifest mapping is available. This means we have to know all the logical path mappings ahead of time. This hasn’t handled any of the aliased cases very well.

If you have app/assets/javascripts/main/index.js, where should it be written to under public? public/assets/main/index-123abc.js or public/assets/main-123abc.js or both? Or should these only be included in the manifest logical path to digest path mapping? That maps ”foo.js” to ”foo-123abc.js”.

Shadow complexities

Assets are always searched in a specific load path order. Aliases will be considered before searching the next load path. This means that alias resolution is affected by load path ordering.

app/assets/javascripts/foo/index.js
vendor/assets/javascripts/foo.js

resolve(“foo.js”) and resolve(“foo/index.js”) should both find the first ”app/assets/javascripts/foo/index.js”.

app/assets/javascripts/foo.js
vendor/assets/javascripts/foo/index.js

In this case resolve(“foo.js”) should find ”app/assets/javascripts/foo.js” and resolve(“foo/index.js”) should find ”vendor/assets/javascripts/foo/index.js”.

This makes it a little tricky to say ”foo/index.js” should always be discovered under ”foo.js” as well.

JS Runtimes

Logical paths tend to leak into JS module systems.

var foo = require(“foo”)

where foo typically maps to the same file sprockets would resolve as ”foo.js”.

You can imagine aliases make this more tricky.

Module systems already have to deal with the logical path -> digest path mapping. A static mapping usually works fine in that case.

Extensibility

It bugs me that the bower behavior had to be built into Sprockets itself. I’m all for supporting it out of the box, but there should be a plugin API that would let people build it if it didn’t exist. Someone should be able to add this behavior to package.json for npm or composer.json, etc.

The resolver alias stuff should be well defined enough that its safe for custom resolvers to be installed.

Possible Solutions

Production Resolver

Right now all Sprockets environment features are disabled in production. Theres no access to the resolver. Hypothetically, that could be enabled so link generation could take advantage of it to generate links.

# ActionView
def asset_path(path)
  digest_path = manifest.assets[resolve(path)]
end

Performance is one concern of this approach. The resolver definitely has to be really fast to run on each request. Though, I’m sure it can be heavily cached in those cases.

A bigger issue with this is that it requires the whole Sprockets environment to be around and initialized. This also means all engines and plugins. When sass is required it installs itself as an engine so .scss files can be recognized. The resolver won’t pick those up without sass being there. Plugins may also install additional load paths to make library assets available. Those will all need to be loaded as well.

I think all that would be possible, but its definitely a pretty big production change and requirement to what we’ve been advocating.

It also doesn’t solve any of the JS runtime aspects. If you have the resolver in production, you’d basically want to implement a duplicate resolve function in JS for your module loader.

Static load path flattening algorithm

On precompile we could basically walk over ever filename in all the load paths, compute all there aliases, and install them into a map.

This basically requires all alias resolvers to implement an inverse alias function. So foo/index.js gives you back foo/index.js and foo.js as potential aliases.

The load path enumeration sorts out of the shadowing priorities.

Some issues with this is that it could potentially be slow. It also increases the burden on the alias resolver API. They need to implement an inverse function. And I’m a little worried about other edge case differences between the regular resolve and inverse resolving.

Alias link gathering

As we compile the asset, we take note of the original logical paths before they were passed to the resolver. This could be stored in the asset metadata blob.

app/assets/javascripts/foo/index.js
# app/assets/javascripts/manifest.js
#= link “foo.js”

Here, we record ”foo.js” before its resolved to ”foo/index.js” in the asset metadata. We can then use this set of paths to populate the static mapping.

The advantage is that we generate the minimal static mapping set since its only the ones the used in the application rather than every possible combination. We also don’t need an inverse function.

Though, this sort of thing is going to depend on manifest linking adoption.

This should work nicely with JS module loaders.

var foo = require(“foo”)

Most module loaders have some sort of prescanning step that will pull out “foo” which can be noted the path. Then the mapping can ensure “foo.js” is available even if its really at “foo/index.js”.

Feedback

Other ideas, thoughts?

/cc @rafaelfranca @arthurnn @matthewd @elia

Incorrect timestamps for images assets

After we started using Sprockets 3 we are seeing some strange timestamps for the image assets. With version 3.0.1 they where set to 'Jan 1 1970', now with 3.0.2 'May 25 2008'.

Perf Review: Cache key digest generation

Hey @tenderlove, now that I have you 😉

I love to know if you have a better idea for implementing this digest generation function. The main use case is generating <255c consistent cache keys. It accepts "simple" nested structured and needs to digest large strings.

https://github.com/rails/sprockets/blob/master/lib/sprockets/digest_utils.rb#L37-L88

Heres a simple use for caching the result of a coffeescript compile

cache.fetch([name, CoffeeScript::Source.version, VERSION, data]) do
 CoffeeScript.compile(data)
end

The entire input data string is used in a key here. That array key gets hashed down to a string that can be used for simple cache = {}; cache[key] lookups or written as the filename when the FS cache store is used.

Have any better implementation ideas here? It doesn't necessarily have to be SHA256 or anything. Just be a consistent hash and work on "simple" ruby objects. Restricting to objects that can be JSON serialized seems like a fine constrain too.

Thanks!

/cc @rafaelfranca

Service Workers (asset served from a custom path)

I'm starting work on integrating ServiceWorker scripts with the asset pipeline, and I'm wondering if there are workarounds for some issues I'm seeing. (Service Workers are a new web feature that gives developers intimate control over how requests are handled; among other things it can be used for building Offline-First web apps.)

One of the properties of a service worker is that a service worker can only control the subdirectory where the script is hosted. A trivial setup would only allow the Service Worker to control the /assets directory. It's preferable to host the script in the root of your domain, so your entire app can be controlled.

I've considered simply placing the script in /public, but that loses all of the features of the asset pipeline. Currently, I've setup a route/controller that reads the script from the sprockets environment and serves it through a controller action. I'm not sure if this would work in a default production setup.

Are there any other ways I could make a script available from the domain root that works reasonable well in development and production?

302 Redirects are not supported. The final path needs to be in the domain root.
I didn't have any issues with fingerprinted files.

Unable to prevent assets from precompiling

I'm storing all the ckeditor assets in the public folder to avoid some of the issues present on the repo. But the assets of the gem are still being compiled. Even though I did:

#assets.rb
Rails.application.config.assets.precompile -= Ckeditor.assets

#ckeditor.rb
Ckeditor.setup do |config|
  config.assets_languages = []
  config.assets_plugins = []
end

Sprockets#logical_paths changed extension name

Hello guys, I have meet a problem related to sprockets in Rails v4.2 but I can not determine if it is a bug from sprockets. The details is below:

  1. I have an image named "something.jpeg" under app/assets/partners/, so the path for it is app/assets/partners/something.jpeg;
  2. I have wrote the below line of code in a template:
<%= image_tag "partners/something.jpeg" %>

ok, everything works well under development environment. But when I started to precompile assets, something weird appears, the precompiled file name was changed to something-e758d2d1631a23e0a91ef8366a803cc3e0d5e48d5ea99f62fd124c21a1911a6c.jpg. See, the extension name of the file was changed from "jpeg" to "jpg", which resulted in that my image can not be shown under production rails environment now.

The rendered template outputs something like:

<img href="images/something.jpeg">

while something like the below is expected:

<img href="/assets/something-e758d2d1631a23e0a91ef8366a803cc3e0d5e48d5ea99f62fd124c21a1911a6c.jpeg">

Now, to resolve the problem, I have to manually change extension names of my special jpeg images.

Additionally, I have debugged and found that the below codes might change extension names of assets:
https://github.com/rails/sprockets/blob/b131fdf727/lib%2Fsprockets%2Flegacy.rb#L109-L111

path, mime_type, _, _ = parse_path_extnames(path)
path = normalize_logical_path(path)
path += mime_types[mime_type][:extensions].first if mime_type

But I am not sure if it is a bug, or if it should be fixed in rails instead. Can anyone help?

fstat unimplemented unsupported or native support failed to load

Anyone have any clue why i'm getting this error from Sprockets 3.0.1?

ENV:
linux (CentOS 6.5)
jruby 1.7.12
Rails 4.1.1
Sprockets 3.0.1

NotImplementedError (fstat unimplemented unsupported or native support failed to load):
  org/jruby/RubyFile.java:1116:in `size'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/cache/file_store.rb:110:in `set'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:274:in `atomic_write'
  org/jruby/RubyIO.java:1182:in `open'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:273:in `atomic_write'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/cache/file_store.rb:108:in `set'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/cache.rb:210:in `set'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/cache.rb:86:in `fetch'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/base.rb:53:in `file_digest'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/loader.rb:160:in `fetch_asset_from_dependency_cache'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/loader.rb:33:in `load'
  vendor/bundle/jruby/1.9/gems/sprockets-3.0.1/lib/sprockets/cached_environment.rb:20:in `initialize'
  org/jruby/RubyProc.java:290:in `call'

Files not loaded/available in development when filename starts with "+"

I put the + symbol in front of the filename when I want it to have higher priority than the rest of the files in a given asset directory.

Example:

[Rails.root]/app/assets/javascripts/page-specific/invoices/+first.js.erb
[Rails.root]/app/assets/javascripts/page-specific/invoices/an_example.js.erb

I get 404's when using the + symbol only after updating sprockets to the latest release. An easy fix is to use underscores but I thought it was something worth mentioning.

Loading sprockets is too slow

I think we can do better:

[aaron@TC sprockets (master)]$ time ruby -v --disable-gems -I lib:../rack/lib -r sprockets -e ''
ruby 2.3.0dev (2015-03-25 trunk 50080) [x86_64-darwin14]

real    0m0.482s
user    0m0.426s
sys 0m0.053s
[aaron@TC sprockets (master)]$

asset compilation benchmark logging was removed

4d47c79

in prior versions you could connect the sprockets logger to rails:

    Rails.application.config.assets.configure do |env|
      env.logger = Rails.logger
    end

and get the following output, when a template referencing the assets was being compiled:

Compiled application.css  (9ms)  (pid 3727)
Compiled jquery.js  (3ms)  (pid 3727)
Compiled jquery_ujs.js  (0ms)  (pid 3727)

this is obviously useful for debugging slow compilation issues, so should return

Sprockets Cookbook

Had an idea for documentation. We should have some sort of section of common sprockets use cases.

Heres some ideas

  • Loading bower packages
  • Organizing multiple bundles to optimize bundle sizes and delivery
  • Adding js/css linters
  • Working with JS module loaders (require.js, browserify)
  • Writing an image format conversation tool
  • Web Worker best practices
  • (your idea here)

What do you guys think? I wonder if this should be something under a docs/ directory here or just under the Wiki for anyone to add ideas?

/cc @rafaelfranca @arthurnn

Absolute resolved file path slows precompilation between deploys

Hi, I'm running into an issue with the way Sprockets resolves asset paths and wanted to see if there was a way to work around it, and if not, what part of the code would be best to modify for a PR.

Basically, the fact that Sprockets resolves asset URIs to a full file:///full/path/to/a/file means that if a project directory which has done a precompile gets moved to a new directory, the precompile loses the advantage of the FileCache and manifest, because Sprockets thinks the files aren't the same because their full path doesn't match, so it doesn't use the files in the cache.

Our project happens to have a lot of assets, which means even a precompile with a manifest and a populated cache causes Sprockets to recalculate the hashes for each asset, and it ends up taking 15-20 minutes whereas in Rails 3 with turbo-sprockets-rails3, the compile took around 5 minutes.

If we run the precompile again without changing the parent directory, it finishes in 10 seconds.

Our Rails 4 app deployment process looks like:

  1. Each release pushed to a timestamped directory like: /data/app/releases/1, /data/app/releases/2, /data/app/releases/3, etc
  2. There's a "current" symlink that points to the most recent release: /data/app/current -> /data/app/releases/3
  3. The Sprockets precompile target directory is a symlink and is shared between all releases, e.g. /data/app/releases/3/public/assets -> /data/app/shared/assets, /data/app/releases/2/public/assets -> /data/app/shared/assets, etc.
  4. The Sprockets cache FileStore directory is a symlink and is shared between all releases, e.g. /data/app/releases/3/tmp/cache -> /data/app/shared/cache, /data/app/releases/2/tmp/cache-> /data/app/shared/cache, etc.
  5. When we deploy, we first push to a new release directory, e.g. /data/app/releases/4
  6. Then, we run the rake assets:precompile task in the new release directory
  7. Since the Sprockets cache filenames are based on the absolute path of the assets, Sprockets doesn't reuse the cached files and the precompile is slower than it has to be.

So I guess my questions are:

  1. Is there any way to have Sprockets use the relative pathname when naming .cache files instead of the full URI?
  2. If not, is there any other way around this?
  3. If not, would you guys be up for a PR that adds a configuration directive or some other way to add this behaviour?

I thought perhaps this wasn't a possibility because of the fact that multiple asset paths could share the same relative paths, but the fact that this was achieved in Rails 3 with turbo-sprockets-rails3 suggests it's possible.

Thanks!

404 on HEAD requests

It seems that locally the asset pipeline only responds to GET requests, not HEAD requests.

GET:

curl 'http://localhost:3000/assets/scriptcam.swf' -X GET -I
HTTP/1.1 200 OK

HEAD:

curl 'http://localhost:3000/assets/scriptcam.swf' -X HEAD -I
HTTP/1.1 404 Not Found

This problem came up because a library I'm using (scriptcam.js) does a HEAD request to check if the file exists first before doing a full GET. In production, it works fine because the files are served up by nginx which knows how to respond to both methods.

What is curious is based on the source code in server.rb that checks the request method, it should actually be responding with a 405 rather than a 404.

Not sure if this should be tagged as a feature request or bug report. It's fairly easy to workaround but it would be nice to be able to have local mirror standard production capabilities.

Timeline for 4.0 release?

There has been some chatter about when we may see a Sprockets 4.0 release over with Opal due to its reliance on Sprockets for sourcemaps. Is there a general sense of what kind of a timeline may exist for a 4.0 drop?

Memory leak in Sprockets v3.0

Hello,

I'm not sure how to be more precise, but there seems to be a memory leak in the asset fetching code in v3.0.

For some reason, we need to provide an HTML page with all assets embedded into the page. That being said, page's <head> looks like this:

    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="..." />

        <%= content_tag :style, type: :'text/css', media: :all do %>
            <%= Rails.application.assets['path/to/template.css'].to_s.html_safe %>
        <% end %>

        <%= javascript_tag do %>
            <%= Rails.application.assets['path/to/template.js'].to_s.html_safe %>
        <% end %>
    </head>

In some cases it takes 5 seconds for this part to render (according to New Relic). Also, there is a memory usage spike that eventually leads to "Memory limit reached" errors (on Heroku).

The problem vanished when I reverted to v2.12.

Please mind that this is happening in production and that assets have already been minified during code deploy.

Thanks!

Edit: Fixed some typos.

Sprockets4 / CommonJS ??

Does Sprockets4 intend to support CommonJS modules and import/export?

Right now I'm using browserify-rails - it works but is slow and doesn't handle style/image assets. My other alternative is a NodeJS build system, but I'd rather avoid that if possible.

ActiveSupport::SafeBuffer not supported as digest class

When I've updated from 2.11.3 to 3.0.2 and running rake assets:precompile I receive the following error:

TypeError: couldn't digest ActiveSupport::SafeBuffer
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/digest_utils.rb:83:in `digest'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/loader.rb:116:in `load_asset_by_uri'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/loader.rb:40:in `block in load'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/loader.rb:170:in `fetch_asset_from_dependency_cache'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/loader.rb:33:in `load'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/cached_environment.rb:20:in `block in initialize'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/cached_environment.rb:47:in `yield'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/cached_environment.rb:47:in `load'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/base.rb:63:in `find_asset'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/base.rb:70:in `find_all_linked_assets'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/manifest.rb:138:in `block in find'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/legacy.rb:114:in `block (2 levels) in logical_paths'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:223:in `block in stat_tree'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:207:in `block in stat_directory'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:204:in `each'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:204:in `stat_directory'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:222:in `stat_tree'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:226:in `block in stat_tree'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:207:in `block in stat_directory'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:204:in `each'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:204:in `stat_directory'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:222:in `stat_tree'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:226:in `block in stat_tree'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:207:in `block in stat_directory'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:204:in `each'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:204:in `stat_directory'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/path_utils.rb:222:in `stat_tree'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/legacy.rb:105:in `each'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/legacy.rb:105:in `block in logical_paths'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/legacy.rb:104:in `each'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/legacy.rb:104:in `logical_paths'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/manifest.rb:136:in `find'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/sprockets/manifest.rb:162:in `compile'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-rails-2.2.4/lib/sprockets/rails/task.rb:70:in `block (3 levels) in define'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-3.0.1/lib/rake/sprocketstask.rb:147:in `with_logger'
/Users/zhivko/.rvm/gems/ruby-2.2.0/gems/sprockets-rails-2.2.4/lib/sprockets/rails/task.rb:69:in `block (2 levels) in define'

Into digest_utils.rb I see that there's no check for that particular class so the TypeError exception is thrown.
When I've changed the check for the String class into digest function on line 53 to

if klass.is_a? String
  digest << obj

it worked.
I tested with 2.11.3 and 2.12.3 and it's working.

If you want me I can provide PR.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.