The concept of immediate value does not exist in Ruby
Now, you might ask "Why does the Ruby FAQ talk about immediate values when Ruby does not have immediate values?" The answer to this question is that, unfortunately, a lot of documentation in the Ruby community mixes up the concept of the programming language called "Ruby" and one of the many Ruby implementations, which unfortunately is also often called "Ruby", although its "official" name is "YARV".
If you check for example the ISO/IEC 30170:2012 Information technology — Programming languages — Ruby specification, you will find no mention of immediate values, neither under that name, nor a similar concept under any other name. They simply don't exist.
Note also the following caveat in the section about immediate values you linked to:
This section or parts of it might be out-dated or in need of confirmation.
So, we have two problems:
- This section talks only about one specific implementation of Ruby, out of many, but it does not make that clear, and
- Even the implementation-specific information is outdated.
In current versions of YARV, Fixnum no longer exists. In the past, Integer was an abstract class with two concrete subclasses: Fixnum and Bignum. Fixnums were immediate values, Bignums were not.
However, depending on whether you were running in 32 bit or 64 bit, the exact same literal could be either a Fixnum, thus an immediate value, or a Bignum. On 32 bit Fixnum could store 31 bit and on 64 bit Fixnum could store 63 bit. Note that this only applies to YARV, though, e.g. JRuby would store 64 bit (not only 63 bit) both on 32 and 64 bit platforms.
Nowadays, Fixnum and Bignum no longer exist, and Integer is a concrete class, not an abstract class. However, the optimization is actually still being performed: YARV still optimizes 31 bit Integers as fixnums on 32 bit systems and 63 bit Integers on 64 bit systems, JRuby still optimizes 64 bit Integers.
JRuby has optimized Floats for a very long time. In JRuby, Floats are immediate values. In YARV, however, there was no such optimization. Floats were not immediate values. Recently, however, YARV has introduced the concept of flonums. Flonums are Floats that fit into 62 bit. Flonums are immediate values. Also, this optimization is only performed on 64 bit platforms, flonums are completely disabled on 32 bit platforms.
Note also that the FAQ completely ignores Symbols which are immediate values in many implementations, including YARV.
So, to answer your question:
Are float immediate values in Ruby?
No. Maybe. Some of them, sometimes.
No, Floats are not immediate values in Ruby, if by "Ruby" you mean "the Ruby Programming Language". The Ruby Language has no concept of immediate values.
Maybe, Floats are immediate values in Ruby, maybe not, if by "Ruby" you mean "the set of all existing Ruby implementations". There are some implementations where under some circumstances, some Float values may or may not be immediate values.
Some Floats are sometimes immediate values, if by "Ruby" you mean "YARV". On 64 bit platforms, a subset of Floats are immediate values, but not all of them. On 32 bit platforms, none are immediate values.
It is irrelevant
You can only figure out whether a value is immediate or not by mutating it. However, all values for which such optimizations are performed, are immutable, can't have instance variables, and can't have singleton methods or a singleton class.
Therefore, it is actually impossible to tell whether something is an immediate value or not. It is a private internal optimization detail.
That means you can simply ignore the concept altogether since there is no way it can make your program run differently.
What about object_id?
First off: Object#object_id is an abomination. It should not exist. Simply forget you ever heard about it.
It violates one of the fundamental principles of object orientation, namely that an object that simulates another object should be indistinguishable from that object. (The same applies to BasicObject#equal?.)
But secondly, here is a counter-example:
# frozen_string_literal: true
# Not immediate values
s1 = '1'
s2 = '1'
s1.object_id
#=> 60
# SAME as `s2`'s id
s2.object_id
#=> 60
# SAME as `s1`'s id
Oops. I broke your test: frozen String literals are not immediate objects, but they are automatically de-duplicated.