String#oct
Overview
String#oct interprets the leading characters of a string as an octal (base-8) number and returns the corresponding integer. It is useful when you have a string representation of an octal number and need to work with its numeric value.
Unlike String#to_i, which defaults to base-10, oct reads the string as base-8. The method also supports binary (0b) and hexadecimal (0x) prefixes, and handles a leading minus sign for negative numbers.
That makes the method handy when you are working with data that already follows Ruby’s numeric literal rules. The important detail is that it reads until the first invalid character, so the conversion is more permissive than strict numeric parsing.
Signature
str.oct -> integer
Takes no arguments. Returns an Integer.
That short signature is one reason the method is easy to use in parsing code. You can call it directly on the string and get an integer back without having to pass an extra base argument every time.
Basic examples
"10".oct # => 8
"010".oct # => 8
"100".oct # => 64
"0".oct # => 0
A leading 0 does not automatically trigger octal interpretation in Ruby — "010".to_i returns 10, not 8. oct exists precisely for this purpose.
The example above shows why the method is useful in the first place: it gives the string a numeric meaning without making you spell out the base every time.
This is a good reminder that oct is about interpretation, not validation. If the text already uses an octal-style prefix or digit pattern, the method can turn it into the integer you expect without extra parsing code.
That distinction matters when the input is stored as text but still needs to behave like a number. oct tells Ruby to treat the leading digits as base-8 instead of letting to_i default to base-10.
Prefix support
oct recognizes binary and hexadecimal prefixes:
"0b10".oct # => 2 (binary)
"0x10".oct # => 16 (hexadecimal)
"-010".oct # => -8 (negative octal)
This cross-base behavior can be convenient, but it can also surprise readers who expect one fixed base. If the input can vary, it is worth checking the prefix rules before relying on the result.
When the data can come from more than one source, it helps to validate the format before conversion. That keeps the logic predictable and makes it easier to explain why a string became a certain integer.
Stopping at non-octal characters
Parsing stops at the first character that is not a valid octal digit (0–7):
"10xyz".oct # => 8 (parses "10", stops at "xyz")
"1_0_1x".oct # => 65 (Ruby 2.0+ ignores digit separators in digit sequences)
Underscore separators in numeric strings are ignored, consistent with Ruby’s numeric literal syntax.
That rule can be useful when the source data is already formatted for readability. It also means a string can keep its separators and still convert cleanly, which makes the method forgiving in import or parsing code.
Invalid or unrecognised leading characters
If the string is empty or begins with no valid octal digits, oct returns 0. This is because octal digits are limited to 0–7, so a leading character like a in "abc" simply doesn’t match any valid digit:
"".oct # => 0
"abc".oct # => 0
If the input can be messy, this forgiving behavior is convenient because the method stays predictable. If you need a failure instead of a fallback, that is the point where Integer() becomes a better fit.
The silent-zero gotcha
A string containing 8 or 9 returns 0, not an error:
"8".oct # => 0
"9".oct # => 0
"080".oct # => 0 (0 is valid, but 8 is not — parsing stops and returns 0)
This silent failure is a common source of bugs. If you expect "080" to produce 64 (the octal interpretation), you will get 0 instead. Always validate input or use Integer() if you need stricter parsing.
Ruby version notes
Ruby 2.0+ ignores digit separators in digit sequences, which matches the behavior shown above.
When you need stricter parsing, Integer() is usually the better choice. oct is designed for convenience and compatibility with Ruby’s numeric syntax, not for rejecting every questionable input.
Strict parsing example
When the input needs to fail loudly instead of returning zero, Integer() is the better fit:
Integer("077")
# => 63
Integer("080")
# => ArgumentError
That trade-off is clearer when the same input is parsed in more than one way: oct follows octal-style rules, while Integer() rejects values that do not fit the expected format.
Comparing common conversion forms
When you want the base choice to stay visible, it helps to show the three forms side by side:
"077".to_i
# => 77
"077".to_i(8)
# => 63
"077".oct
# => 63
Seeing the three forms side by side makes the base choice obvious. to_i defaults to base-10, to_i(8) spells out the base directly, and oct follows Ruby’s octal rules.
When you are reading imported data, that side-by-side view is often the quickest way to see why a value landed on a different integer than expected. It turns the base choice into something visible instead of implicit.
"08".oct
# => 0
Integer("08")
# => ArgumentError
That edge case is where the difference matters most: the permissive parser falls back to zero, while Integer() refuses the invalid digit and raises immediately. When writing validation code, this distinction determines whether a malformed input becomes a silent zero or a visible exception that stops execution.
Another quick comparison with base-10 parsing can be useful when the input starts with a zero but still needs to stay predictable:
"010".to_i
# => 10
"010".oct
# => 8
That tiny difference is easy to miss in a long parsing pipeline. Showing both versions side by side keeps the intent clear and makes the fallback behavior easier to remember. A leading zero changes the result dramatically depending on which method you call, so keeping a quick reference table nearby saves debugging time.
"077".to_i(8)
# => 63
That extra example shows the same octal result through a different API, which is useful when you want the base to be obvious in the call itself. Seeing to_i(8) and oct produce the same result side by side confirms that both paths lead to the same integer, which can be reassuring during code review.
"077".oct
# => 63
oct keeps the base-8 intent local to the method name, while to_i(8) makes the base explicit in the argument list. Both are valid, and the better choice depends on which style reads more clearly in the surrounding code. If the team convention favours method names over argument-passing for readability, oct usually fits better.
More prefix examples
oct also follows the same prefix rules when the input looks like another Ruby literal. These shorter examples make that behavior easy to scan:
"0b1010".oct
# => 10
"0x1f".oct
# => 31
The binary and hex forms show that oct follows Ruby’s literal-style prefixes as well as plain octal digits. This prefix recognition makes the method more versatile than a strict octal-only parser, though it also means you should verify the format if the input source is not trusted.
Invalid input recap
The fallback-to-zero behavior is the part worth remembering for messy input:
"abc".oct
# => 0
"08".oct
# => 0
If the input should never disappear into zero, Integer() is the stricter choice. That makes the failure visible instead of hiding it in a default result.
Practical parsing example
When reading configuration values that mix decimal and octal defaults, oct handles both formats without extra branching:
def parse_mode(value)
value.oct
end
parse_mode("644") # => 420 (octal, same as Unix file permissions)
parse_mode("10") # => 8 (octal)
parse_mode("0x1F") # => 31 (hex, via prefix)
This approach works well for permission masks, flag fields, and any setting where the format may vary but the numeric result is what matters downstream.
See Also
- String#hex — converts leading hex digits to an integer
- Integer class — Ruby’s integer type and related conversion methods