class Sprockets::Asset

‘Asset` is the base class for `BundledAsset` and `StaticAsset`.

def self.from_hash(environment, hash)

Internal initializer to load `Asset` from serialized `Hash`.
def self.from_hash(environment, hash)
  asset = allocate
  asset.init_with(environment, hash)
  asset
end

def self.serialized_attributes

Define base set of attributes to be serialized.
def self.serialized_attributes
  %w( id logical_path pathname )
end

def content_type

Returns `Content-Type` from pathname.
def content_type
  @content_type ||= environment.content_type_of(pathname)
end

def dependencies

Return an `Array` of `Asset` files that are declared dependencies.
def dependencies
  []
end

def dependency_fresh?(dep = {})

want to test non-asset files and directories.
A `Hash` is used rather than other `Asset` object because we

`dep` is a `Hash` with `path`, `mtime` and `hexdigest` keys.

Check if dependency is fresh.
def dependency_fresh?(dep = {})
  path, mtime, hexdigest = dep.values_at('path', 'mtime', 'hexdigest')
  stat = environment.stat(path)
  # If path no longer exists, its definitely stale.
  if stat.nil?
    return false
  end
  # Compare dependency mime to the actual mtime. If the
  # dependency mtime is newer than the actual mtime, the file
  # hasn't changed since we created this `Asset` instance.
  #
  # However, if the mtime is newer it doesn't mean the asset is
  # stale. Many deployment environments may recopy or recheckout
  # assets on each deploy. In this case the mtime would be the
  # time of deploy rather than modified time.
  if mtime >= stat.mtime
    return true
  end
  digest = environment.file_digest(path)
  # If the mtime is newer, do a full digest comparsion. Return
  # fresh if the digests match.
  if hexdigest == digest.hexdigest
    return true
  end
  # Otherwise, its stale.
  false
end

def digest

Get content digest at the time the `Asset` is built.
def digest
  @digest ||= environment.file_digest(pathname).hexdigest
end

def digest_path


"foo/bar-37b51d194a7513e45b56f6524f2d51f2.js"

Return logical path with digest spliced in.
def digest_path
  environment.attributes_for(logical_path).path_with_fingerprint(digest)
end

def each

compatible body objects.
Add enumerator to allow `Asset` instances to be used as Rack
def each
  yield to_s
end

def encode_with(coder)

Copy serialized attributes to the coder object
def encode_with(coder)
  coder['class'] = self.class.name.sub(/Sprockets::/, '')
  self.class.serialized_attributes.each do |attr|
    value = send(attr)
    coder[attr] = case value
      when Time
        value.iso8601
      else
        value.to_s
      end
  end
  coder['pathname'] = relativize_root_path(coder['pathname'])
end

def eql?(other)

Assets are equal if they share the same path, mtime and digest.
def eql?(other)
  other.class == self.class &&
    other.relative_pathname == self.relative_pathname &&
    other.mtime.to_i == self.mtime.to_i &&
    other.digest == self.digest
end

def expand_root_path(path)

Replace `$root` placeholder with actual environment root.
def expand_root_path(path)
  environment.attributes_for(path).expand_root
end

def fresh?

Subclass must override `fresh?` or `stale?`.

Used to test if cached models need to be rebuilt.

digest to the inmemory model.
Checks if Asset is fresh by comparing the actual mtime and
def fresh?
  !stale?
end

def init_with(environment, coder)

Initialize `Asset` from serialized `Hash`.
def init_with(environment, coder)
  @environment = environment
  @pathname = @mtime = @length = nil
  self.class.serialized_attributes.each do |attr|
    instance_variable_set("@#{attr}", coder[attr].to_s) if coder[attr]
  end
  if @pathname && @pathname.is_a?(String)
    # Expand `$root` placeholder and wrapper string in a `Pathname`
    @pathname = Pathname.new(expand_root_path(@pathname))
  end
  if @mtime && @mtime.is_a?(String)
    # Parse time string
    @mtime = Time.parse(@mtime)
  end
  if @length && @length.is_a?(String)
    # Convert length to an `Integer`
    @length = Integer(@length)
  end
end

def initialize(environment, logical_path, pathname)

def initialize(environment, logical_path, pathname)
  @environment  = environment
  @logical_path = logical_path.to_s
  @pathname     = Pathname.new(pathname)
  @id           = environment.digest.update(object_id.to_s).to_s
end

def inspect

Pretty inspect
def inspect
  "#<#{self.class}:0x#{object_id.to_s(16)} " +
    "pathname=#{pathname.to_s.inspect}, " +
    "mtime=#{mtime.inspect}, " +
    "digest=#{digest.inspect}" +
    ">"
end

def length

Get length at the time the `Asset` is built.
def length
  @length ||= environment.stat(pathname).size
end

def mtime

Get mtime at the time the `Asset` is built.
def mtime
  @mtime ||= environment.stat(pathname).mtime
end

def relative_pathname

Get pathname with its root stripped.
def relative_pathname
  Pathname.new(relativize_root_path(pathname))
end

def relativize_root_path(path)

Replace actual environment root with `$root` placeholder.
def relativize_root_path(path)
  environment.attributes_for(path).relativize_root
end

def stale?

Subclass must override `fresh?` or `stale?`.

digest to the inmemory model.
Checks if Asset is stale by comparing the actual mtime and
def stale?
  !fresh?
end

def to_a

purposes.
This allows you to link to individual files for debugging

the asset's contents as a whole.
Appending all of an assets body parts together should give you

Expand asset into an `Array` of parts.
def to_a
  [self]
end