1

I'm doing a ruby challenge that I found on rubeque.com. Here are the instructions:

Instructions: Write a method #r_empty? that returns true if a hash and its subhashes are empty or false if there is a value in the hash.

My Answer:

class Hash
    def r_empty?
        def recurse(h)
            h.each {|key, value|
                value.is_a?(Hash) ? recurse(value) : 
            if (value!=nil && value!="")
                #puts value
                return false
            end
            }
        return true             
        end
    recurse(self)
    end
end

Test:

a = {:ruby => "", :queue => ""}    
b = {:ruby => {:version => {:one => {"nine" => ""}, "two" => "=^.^="}}, 
:html => ""}    
c = {:pets => {:dogs => {:my => {"niko" => ""}, "ollie" => ""}}, :cats => 
nil, :mice => ""}    
d = {a: "", b: :two, c: ""}

Answers:

a.r_empty?, true    
b.r_empty?, false    
c.r_empty?, true    
d.r_empty?, false    
({}.r_empty?), true   

Using this code, I was able to get the right answer for 4 out of the 5 tests. My method returns TRUE for b.r_empty? ... I do notice that if I uncomment out #puts value, "=^.^=" is printed out for b.r_empty? ... So the if statement is being executed, but ultimately false is not returned. I'm still a ruby novice so I will gladly appreciate any advice and guidance towards the right topics i should go over for this challenge.

2
  • Cannot be reproduced. Commented Nov 2, 2017 at 6:04
  • 1
    My bad, Class is capitalized for some reason.. so it's supposed to be class Hash {..rest of code..}, let me know if there's any more problems Commented Nov 2, 2017 at 6:30

1 Answer 1

1

Although it's cool to define a method inside another (I did not know this was possibly actually) the method can be simplified quite a bit:

class Hash
  def r_empty?
    !values.any? do |val|
       val.is_a?(Hash) ? !val.r_empty? : (val && val != "")
    end
  end
end

I'm not sure exactly the problem is with your original code, however I think the recurse(value) is effectively being discarded.

By the way, in terms of style I recommend only using a ternary for single-line expressions and also being diligent about consistent indentation.

Sign up to request clarification or add additional context in comments.

8 Comments

Awesome, it works! Could you give me a quick overview of the logic behind your code? I'll also actively google and look up the docs for the methods you used.
The only methods I used that aren't in the original are Hash#values (returns an array, similar to Hash#keys) and Enumerable#any?.
To understand it you can kind of read it like pseudocode: Are none of the values either: a. hashes containing some non-blank value or b. non-blank values?. Also keep in mind that Rails comes with a method Object#blank? which covers this nil-or-empty-string use-case.
!values.any? could be simplified to values.none?
@maxpleaner: it is not actually possible to define methods inside one another. The syntax is valid, yes, but the inner method will be defined on the same scope as the outer method. It will not be hidden in the outer method (unlike in some other languages)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.