Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add depth option #86

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

gabrielcosta42
Copy link

Feature requested on #84.

Adds a 'depth' option to limit how many times the multiline can be repeated on nested objects.

Applied to:

  • Arrays
  • Hashes
  • Structs
  • Objects that can use multiline option
ap(a)
# [
#     [0] [
#         [0] [
#             [0] 1,
#             [1] 2
#         ],
#         [1] [
#             [0] 3,
#             [1] 4
#         ]
#     ],
#     [1] {
#         :a => "x",
#         :b => {
#             :x => "a",
#             :y => "b",
#             :z => "c"
#         },
#         :c => "z"
#     }
# ]

ap(a, depth:2)
# [
#     [0] [
#         [0] [ 1, 2 ],
#         [1] [ 3, 4 ]
#     ],
#     [1] {
#         :a => "x",
#         :b => { :x => "a", :y => "b", :z => "c" },
#         :c => "z"
#     }
# ]

ap(a, depth:1)
# [
#     [0] [ [ 1, 2 ], [ 3, 4 ] ],
#     [1] { :a => "x", :b => { :x => "a", :y => "b", :z => "c" }, :c => "z" }
# ]

ap(a, depth:0)
# [ [ [ 1, 2 ], [ 3, 4 ] ], { :a => "x", :b => { :x => "a", :y => "b", :z => "c" }, :c => "z" } ]

@joeyparis
Copy link

I would love to see this merged in

Copy link
Member

@HarlemSquirrel HarlemSquirrel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is super nice! Thank you for all this work!

I have a few small suggestions.

I'm also thinking that for really large objects we might want to truncate nested objects rather than just put them on a single line. That could be a later enhancement.

end

def reached_depth_limit
!depth_limit.nil? && depth >= depth_limit
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice for this to live in something like DepthTracker#reached_depth_limit?

!depth_limit.nil? && depth >= depth_limit
end

def single_line_if_reached_depth(&blk)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛏️ what do you think of changing this method name to with_depth_tracking?

@@ -44,6 +44,7 @@ raw: false, # Do not recursively format instance variables.
sort_keys: false, # Do not sort hash keys.
sort_vars: true, # Sort instance variables.
limit: false, # Limit arrays & hashes. Accepts bool or int.
depth: nil, # Limit number of nested objects the multiline can go deep.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than adding a new configuration, what do you think of allowing multiline to be an integer? We could support both true/false and 0+ values

@HarlemSquirrel HarlemSquirrel requested a review from paddor July 1, 2022 18:41
Copy link
Contributor

@paddor paddor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like @HarlemSquirrel's suggestions.

@HarlemSquirrel
Copy link
Member

@gabrielcosta42 have you had a chance to look over the suggestions?

@HarlemSquirrel
Copy link
Member

@gabrielcosta42 checking in to see if you have some time to review my suggestions.

@HarlemSquirrel
Copy link
Member

@gabrielcosta42 Checking to see if you have any time to finish up this pull request for Hacktoberfest

@admsev
Copy link

admsev commented May 30, 2024

@gooroodev can you review this PR?

@gooroodev
Copy link

Thank you for tagging me, @admsev!

Mistakes Typos Security Performance Best Practices Readability Others
0 0 0 0 1 1 0

Summary of Changes

  • ➕ Added a new feature to limit the depth of nested objects in the multiline output.
  • 📖 Improved readability by adding the depth option to the README.md file.
  • ➕ Introduced a new DepthTracker class to manage depth tracking.
  • ➕ Added depth-related methods in base_formatter.rb and integrated them into array_formatter.rb, hash_formatter.rb, object_formatter.rb, and struct_formatter.rb.
  • ➕ Added new test cases in formats_spec.rb to verify the functionality of the depth option.

Identified Issues

ID Type Details Severity Confidence
1 Best Practices The track_depth method in DepthTracker should ensure the block is provided. 🟡 Low 🟡 Low
2 Readability The single_line_if_reached_depth method could benefit from a more descriptive name. 🟡 Low 🟡 Low

Proposed Fixes

1. Ensure Block is Provided in track_depth Method

  • File: lib/amazing_print/depth_tracker.rb
  • Lines: 13-14
  • Change: Add a check to ensure a block is provided to track_depth.
def track_depth
  raise "No block given" unless block_given?
  @depth += 1
  yield
ensure
  @depth -= 1
end

2. Rename single_line_if_reached_depth Method for Clarity

  • File: lib/amazing_print/formatters/base_formatter.rb
  • Lines: 156-164, 170-172
  • Change: Rename single_line_if_reached_depth to force_single_line_if_depth_limit_reached.
def force_single_line_if_depth_limit_reached(&blk)
  multiline = options[:multiline]
  options[:multiline] = false if reached_depth_limit
  track_depth { yield }
ensure
  options[:multiline] = multiline
end
  • File: lib/amazing_print/formatters/array_formatter.rb
  • Lines: 13-17
  • Change: Update method call in array_formatter.rb.
def simple_array
  force_single_line_if_depth_limit_reached do
    if options[:multiline]
      multiline_array
    else
      "[ #{array.map { |item| inspector.awesome(item) }.join(', ')} ]"
    end
  end
end
  • File: lib/amazing_print/formatters/hash_formatter.rb
  • Lines: 28-36
  • Change: Update method call in hash_formatter.rb.
def simple_hash
  force_single_line_if_depth_limit_reached do
    if multiline_hash?
      multiline_hash
    else
      "{ #{printable_hash.join(', ')} }"
    end
  end
end
  • File: lib/amazing_print/formatters/object_formatter.rb
  • Lines: 30-44
  • Change: Update method call in object_formatter.rb.
single_line_if_reached_depth do
  data = (options[:sort_vars] ? vars.sort : vars).map do |declaration, var|
    key = left_aligned do
      align(declaration, declaration.size)
    end

    unless options[:plain]
      key = if key =~ /(@\w+)/
              key.sub(Regexp.last_match(1), colorize(Regexp.last_match(1), :variable))
            else
              key.sub(/(attr_\w+)\s(:\w+)/, "#{colorize('\\1', :keyword)} #{colorize('\\2', :method)}")
            end
    end

    indented do
      key + colorize(' = ', :hash) + inspector.awesome(object.instance_variable_get(var))
    end
  end

  if options[:multiline]
    "#<#{awesome_instance}\n#{data.join(%(,\n))}\n#{outdent}>"
  else
    "#<#{awesome_instance} #{data.join(', ')}>"
  end
end
  • File: lib/amazing_print/formatters/struct_formatter.rb
  • Lines: 30-44
  • Change: Update method call in struct_formatter.rb.
single_line_if_reached_depth do
  data = vars.sort.map do |declaration, var|
    key = left_aligned do
      align(declaration, declaration.size)
    end

    unless options[:plain]
      key = if key =~ /(@\w+)/
              key.sub(Regexp.last_match(1), colorize(Regexp.last_match(1), :variable))
            else
              key.sub(/(attr_\w+)\s(:\w+)/, "#{colorize('\\1', :keyword)} #{colorize('\\2', :method)}")
            end
    end

    indented do
      key + colorize(' = ', :hash) + inspector.awesome(struct.send(var))
    end
  end

  if options[:multiline]
    "#<#{awesome_instance}\n#{data.join(%(,\n))}\n#{outdent}>"
  else
    "#<#{awesome_instance} #{data.join(', ')}>"
  end
end

General Review

The code changes introduce a new feature to limit the depth of nested objects in the multiline output. The implementation is well-structured and integrates seamlessly with the existing codebase. The addition of the DepthTracker class and the depth-related methods in the formatters is a clean solution to the problem. The test cases added in formats_spec.rb are comprehensive and ensure the new feature works as expected. The overall code quality and style are consistent with the existing code, and the changes improve the functionality of the library without introducing any significant issues.

--
I only arrive when I am mentioned and asked to review the pull request.
React or reply to let me know your feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants