<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _metahash(self):
 """Checksum hash of all the inputs to this rule. Output is invalid until collect_srcs and collect_deps have been run. In theory, if this hash doesn't change, the outputs won't change either, which makes it useful for caching. """


        # BE CAREFUL when overriding/extending this method. You want to copy
        # the if(cached)/return(cached) part, then call this method, then at
        # the end update the cached metahash. Just like this code, basically,
        # only you call the method from the base class in the middle of it. If
        # you get this wrong it could result in butcher not noticing changed
        # inputs between runs, which could cause really nasty problems.
        # TODO(ben): the above warning seems avoidable with better memoization

        if self._cached_metahash:
            return self._cached_metahash

        # If you are extending this function in a subclass,
        # here is where you do:
        # BaseBuilder._metahash(self)

        log.debug('[%s]: Metahash input: %s', self.address,
                  unicode(self.address))
        mhash = util.hash_str(unicode(self.address))
        log.debug('[%s]: Metahash input: %s', self.address, self.rule.params)
        mhash = util.hash_str(str(self.rule.params), hasher=mhash)
        for src in self.rule.source_files or []:
            log.debug('[%s]: Metahash input: %s', self.address, src)
            mhash = util.hash_str(src, hasher=mhash)
            mhash = util.hash_file(self.srcs_map[src], hasher=mhash)
        for dep in self.rule.composed_deps() or []:
            dep_rule = self.rule.subgraph.node[dep]['target_obj']
            for item in dep_rule.output_files:
                log.debug('[%s]: Metahash input: %s', self.address, item)
                item_path = os.path.join(self.buildroot, item)
                mhash = util.hash_str(item, hasher=mhash)
                mhash = util.hash_file(item_path, hasher=mhash)
        self._cached_metahash = mhash
        return mhash