fn eq(&self, other: &Self) -> bool {
        if self.id() == other.id() {
            return true;
        };
        if self.is_packed_value() || other.is_packed_value() {
            if let Some(lhsi) = self.as_fixnum() {
                if let Some(rhsf) = other.as_flonum() {
                    return lhsi as f64 == rhsf;
                }
            } else if let Some(lhsf) = self.as_flonum() {
                if let Some(rhsi) = other.as_fixnum() {
                    return rhsi as f64 == lhsf;
                }
            }
            return false;
        }
        let (lhs, rhs) = (self.rvalue(), other.rvalue());
        match (lhs.kind(), rhs.kind()) {
            (ObjKind::BIGNUM, ObjKind::BIGNUM) => *lhs.bignum() == *rhs.bignum(),
            (ObjKind::BIGNUM, ObjKind::FLOAT) => lhs.bignum().to_f64().unwrap() == rhs.float(),
            (ObjKind::FLOAT, ObjKind::FLOAT) => lhs.float() == rhs.float(),
            (ObjKind::FLOAT, ObjKind::BIGNUM) => lhs.float() == rhs.bignum().to_f64().unwrap(),
            (ObjKind::COMPLEX, ObjKind::COMPLEX) => {
                let RubyComplex { r: r1, i: i1 } = *lhs.complex();
                let RubyComplex { r: r2, i: i2 } = *rhs.complex();
                r1.eq(&r2) && i1.eq(&i2)
            }
            (ObjKind::STRING, ObjKind::STRING) => {
                lhs.string().as_bytes() == rhs.string().as_bytes()
            }
            (ObjKind::ARRAY, ObjKind::ARRAY) => **lhs.array() == **rhs.array(),
            (ObjKind::RANGE, ObjKind::RANGE) => {
                let (lhs, rhs) = (&*lhs.range(), &*rhs.range());
                lhs.exclude == rhs.exclude && lhs.start == rhs.start && rhs.end == lhs.end
            }
            (ObjKind::HASH, ObjKind::HASH) => *lhs.rhash() == *rhs.rhash(),
            (ObjKind::REGEXP, ObjKind::REGEXP) => *lhs.regexp() == *rhs.regexp(),
            (ObjKind::TIME, ObjKind::TIME) => *lhs.time() == *rhs.time(),
            (ObjKind::PROC, ObjKind::PROC) => *lhs.proc() == *rhs.proc(),
            (ObjKind::METHOD, ObjKind::METHOD) => *lhs.method() == *rhs.method(),
            (ObjKind::UNBOUND_METHOD, ObjKind::UNBOUND_METHOD) => *lhs.method() == *rhs.method(),
            (ObjKind::INVALID, _) => {
                unreachable!("Invalid rvalue. (maybe GC problem) {:?}", self.rvalue())
            }
            (_, ObjKind::INVALID) => {
                unreachable!("Invalid rvalue. (maybe GC problem) {:?}", other.rvalue())
            }
            (_, _) => false,
        }
    }
Equality of value.

This kind of equality is used for `==` operator of Ruby.
Generally, two objects which all of properties are `eq` are defined as `eq`.
Some classes have original difinitions of `eq`.

ex. 3.0 == 3.
ruruby/src/value/value.rs