# Can anyone tell me why my code isn't working?

**URL:** <https://www.ruby-forum.com/t/can-anyone-tell-me-why-my-code-isnt-working/151399>\
**Category:** Ruby\
**Created:** [October 21, 2008, 12:37am UTC](https://www.ruby-forum.com/t/can-anyone-tell-me-why-my-code-isnt-working/151399 "2008-10-21T00:37:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tcm614ce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/47e85d/32.png) [@tcm614ce](https://www.ruby-forum.com/u/tcm614ce)\
**Post date:** [October 21, 2008, 12:37am UTC](https://www.ruby-forum.com/t/can-anyone-tell-me-why-my-code-isnt-working/151399/1 "2008-10-21T00:37:50Z")

</div>

Hi there,

For some reason the get\_mac\_by\_printer(host\_name) method isn’t working.  
All the other bits work, but I have a feeling that I’m running into a  
problem with variables defined within blocks, but I’m at a loss as to  
how to negotiate it. The resulting mac is returning as nilClass and it  
definitely isn’t nil! Code as follows:

#Class for handling the plist file.  
class PlistHash  
def initialize(path)  
@path=path  
@plist\_hash=Plist::parse\_xml(@path)  
end

def get\_mac\_by\_host(host\_name)  
servers=@plist\_hash[‘servers’].each do |s|  
mac=s[‘mac’] if s[‘name’]==host\_name  
return mac  
end  
end

def get\_mac\_by\_printer(printer\_name)  
printers=@plist\_hash[‘printers’]  
printers.each do |v|  
host=v[‘host’] if v[‘name’]==printer\_name  
return host  
end  
mac=get\_mac\_by\_host(host)  
return mac  
end

def get\_broadcast\_ip  
broadcast\_ip=@plist\_hash[‘broadcastIP’]  
end  
end

Thanks for your help,

Adam

---

<div class="post-metadata">

**Author:** ![tcm614ce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/47e85d/32.png) [@tcm614ce](https://www.ruby-forum.com/u/tcm614ce)\
**Post date:** [October 21, 2008, 1:39am UTC](https://www.ruby-forum.com/t/can-anyone-tell-me-why-my-code-isnt-working/151399/2 "2008-10-21T01:39:54Z")

</div>

Solved it.

I came up with this solution to force the each loops to return a  
specific value from the array of hashes. Explicitly returning the value  
of the block each block did the trick. Still don’t think I’ve got the  
hang of variable scope though. ☹

class PlistHash  
def initialize(path)  
@plist\_hash=Plist::parse\_xml(path)  
end

def get\_mac\_by\_host(host\_name)  
servers=@plist\_hash[‘servers’].each do |s|  
return s[‘mac’] if s[‘name’]==host\_name  
end  
end

def get\_host\_by\_printer(printer\_name)  
printers=@plist\_hash[‘printers’]  
printers.each do |v|  
return v[‘server’] if v[‘name’]==printer\_name  
end  
end  
def get\_mac\_by\_printer(printer\_name)  
host=self.get\_host\_by\_printer(printer\_name)  
return self.get\_mac\_by\_host(host)  
end

def get\_broadcast\_ip  
broadcast\_ip=@plist\_hash[‘broadcastIP’]  
end  
end

---

<div class="post-metadata">

**Author:** ![tcm614ce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/47e85d/32.png) [@tcm614ce](https://www.ruby-forum.com/u/tcm614ce)\
**Post date:** [October 21, 2008, 9:59am UTC](https://www.ruby-forum.com/t/can-anyone-tell-me-why-my-code-isnt-working/151399/3 "2008-10-21T09:59:52Z")

</div>

Adam P. wrote:

> For some reason the get\_mac\_by\_printer(host\_name) method isn’t working.  
> All the other bits work, but I have a feeling that I’m running into a  
> problem with variables defined within blocks, but I’m at a loss as to  
> how to negotiate it.

No, nothing to do with variable scoping.

> The resulting mac is returning as nilClass and it  
> definitely isn’t nil! Code as follows:  
> …  
> def get\_mac\_by\_host(host\_name)  
> servers=@plist\_hash[‘servers’].each do |s|  
> mac=s[‘mac’] if s[‘name’]==host\_name  
> return mac  
> end  
> end

It definitely _is_ nil.

Note that your ‘each’ loop will onlyever run for one iteration, since  
‘return mac’ will always return from the enclosing method  
(get\_mac\_by\_host) during the first iteration. So, unless the passed  
host\_name happens to match the first entry of @plist\_hash[‘servers’],  
then the assignment

mac = s[‘mac’] if s[‘name’]==host\_name

will not be executed (because it’s qualified by “if … false condition  
…”), so the value of the local variable ‘mac’ will be nil.

To demonstrate:

if 1 == 2  
foo = “oops”  
end  
puts foo # nil

So your loop is similar to:

def mycode  
(1…5).each do |v|  
res = v if v == 3  
return res  
end  
end  
puts mycode # nil

You could fix this by changin “return res” to “return res if v == 3”, or  
“return res if res”, but more simply

def mycode  
(1…5).each do |v|  
return v if v == 3  
end  
end  
puts mycode # 3

---

<div class="post-metadata">

**Author:** ![tcm614ce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/47e85d/32.png) [@tcm614ce](https://www.ruby-forum.com/u/tcm614ce)\
**Post date:** [October 21, 2008, 10:35am UTC](https://www.ruby-forum.com/t/can-anyone-tell-me-why-my-code-isnt-working/151399/4 "2008-10-21T10:35:49Z")

</div>

On Tue, Oct 21, 2008 at 9:59 AM, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> You could fix this by changin “return res” to “return res if v == 3”, or  
> “return res if res”, but more simply
> 
> def mycode  
> (1…5).each do |v|  
> return v if v == 3  
> end  
> end  
> puts mycode # 3

Also check Enumerable#find:

irb(main):002:0\> a = [{:name =\> “a”, :value =\> 3}, {:name =\> “b”,  
:value =\> 4}, {:name =\> “c”, :value =\> 10}]  
=\> [{:value=\>3, :name=\>“a”}, {:value=\>4, :name=\>“b”}, {:value=\>10,  
:name=\>“c”}]  
irb(main):003:0\> a.find {|s| s[:name] == “b”}  
=\> {:value=\>4, :name=\>“b”}

So, you method could be done as:

def get\_mac\_by\_host(host\_name)  
s = @plist\_hash[‘servers’].find {|s| s[‘name’] == host\_name}  
return s[‘mac’] if s  
nil  
end

(not tested). Hope this helps,

Jesus.

---

<div class="post-metadata">

**Author:** ![tcm614ce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/47e85d/32.png) [@tcm614ce](https://www.ruby-forum.com/u/tcm614ce)\
**Post date:** [October 21, 2008, 10:48am UTC](https://www.ruby-forum.com/t/can-anyone-tell-me-why-my-code-isnt-working/151399/5 "2008-10-21T10:48:23Z")

</div>

Just to make the semantics of ‘return’ clearer:

def foo  
1  
return 2  
raise “Never get here”  
3  
end

puts foo # 2

return doesn’t cause store a value for returning later; it causes the  
method to return immediately, returning that value.
