String#byteslice

str.byteslice(index) or str.byteslice(start, length)
Returns: String or nil · Added in v1.8.7 · Updated March 13, 2026 · String Methods
ruby string bytes encoding extraction

The byteslice method extracts a portion of a string based on byte positions rather than character positions. This is essential when working with binary data, specific byte-level operations, or when you need precise control over multi-byte character encodings like UTF-8.

Unlike slice, which works with character indices, byteslice operates at the byte level. This distinction becomes critical when working with non-ASCII characters where a single character may occupy multiple bytes.

Syntax

str.byteslice(index)           # Single byte position
str.byteslice(start, length)   # Range of bytes
str.byteslice(range)            # Byte range

Parameters

  • index — A zero-based byte position (Integer)
  • start — The starting byte position (Integer)
  • length — The number of bytes to extract (Integer)
  • range — A Range of byte positions

Return Value

Returns a new string containing the extracted bytes, or nil if the index is out of bounds.

Examples

Basic byte extraction

ascii = "hello"
ascii.byteslice(0)   # => "h"
ascii.byteslice(1)   # => "e"
ascii.byteslice(-1)  # => "o"

Extracting a byte range

"hello".byteslice(1, 3)
# => "ell"

"hello".byteslice(1..3)
# => "ell"

Working with multi-byte characters

When dealing with UTF-8 encoded strings, characters beyond ASCII occupy multiple bytes:

text = "こんにちは"  # 5 characters, 15 bytes in UTF-8

text.byteslice(0)   # Returns nil because first character starts at byte 0 but is 3 bytes long
text.byteslice(0, 3)  # => "こ" - first 3 bytes form the first character
text.byteslice(3, 3)  # => "ん" - bytes 3-5 form the second character

Comparing byteslice vs slice

text = "日本"

text.slice(0)        # => "日"  - character at position 0
text.byteslice(0)     # => nil   - cannot extract single byte from 3-byte character

text.slice(0, 1)     # => "日"  - 1 character
text.byteslice(0, 1) # => nil    - returns nil for partial character
text.byteslice(0, 3) # => "日"   - 3 bytes = 1 complete character

Common Use Cases

Extract bytes from binary data

data = "\xFF\xFE\x00\x01"

data.byteslice(0, 2)  # => "\xFF\xFE"
data.byteslice(2, 2)  # => "\x00\x01"

Parse byte-level protocols

def extract_header(bytes)
  {
    version: bytes.byteslice(0, 1).ord,
    flags: bytes.byteslice(1, 1).ord,
    length: bytes.byteslice(2, 2).unpack("n").first
  }
end

Handle encoding edge cases

def truncate_to_bytes(str, max_bytes)
  return "" if max_bytes <= 0
  
  str.byteslice(0, max_bytes) || str
end

truncate_to_bytes("こんにちは", 6)
# => "こん" - cuts at byte boundary, not character

Error Handling

byteslice returns nil when the index is out of bounds, making it safe to use without raising errors:

"hi".byteslice(10)     # => nil
"hi".byteslice(-10)    # => nil
"".byteslice(0)        # => nil

However, when using the two-argument form with invalid arguments, it still returns nil:

"hello".byteslice(0, -1)  # => nil (negative length)

Performance

byteslice is efficient because it creates a new string from existing bytes without re-encoding:

text = "hello world"
text.byteslice(0, 5)  # => "hello" - no re-encoding needed

See Also