0

how do I extract @hostname value out of this data? e.g. to do what I was expecting puts output[:hostname]

{:status=>"passed",
 :code_desc=>"Host example.com port 80 proto tcp is expected to be reachable",
 :run_time=>0.207583,
 :start_time=>"2020-08-27T21:02:07+01:00",
 :resource_title=>
  #<#<Class:0x00007f87f71ebeb0>:0x00007f87f71eaf38
   @__backend_runner__=
    Inspec::Backend::Class @transport=Train::Transports::Local::Connection,
   @__resource_name__=:host,
   @host_provider=
    #<Inspec::Resources::DarwinHostProvider:0x00007f87f71e9a20
     @has_nc=true,
     @has_ncat=true,
     @has_net_redirections=true,
     @inspec=
      Inspec::Backend::Class @transport=Train::Transports::Local::Connection>,
   @hostname="example.com",
   @ip_cache=["93.184.216.34", "2606:2800:220:1:248:1893:25c8:1946"],
   @ping_cache=
    {:success=>true,
     :connection=>"Connection to example.com port 80 [tcp/http] succeeded!\n",
     :socket=>""},
   @port=80,
   @protocol="tcp",
   @resource_exception_message=nil,
   @resource_failed=false,
   @resource_skipped=false,
   @supports=[{:platform=>"unix"}, {:platform=>"windows"}]>,
 :expectation_message=>"is expected to be reachable",
 :waiver_data=>nil}

Any help on documentation would be very gratefully received.

3 Answers 3

6

If there's no accessor method Kaom Te writes about here https://stackoverflow.com/a/63623855/299774, then use instance_variable_get like this:

output[:resource_title].instance_variable_get(:@hostname)

But! Be careful! The fact that someone didn't provide this accessor as a public method means they wanted to encapsulate this data.

So, if you're doing it for some production system - it can surprise you to learn after next gem update that @hostname is no longer there (name was changed), or (even worse) it's still there but contains different data. It's an internal implementation detail that might be subject for change.

On the other hand, if this object comes from an open-source project - make a PR and make it part of a public interface.

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

Comments

2

Assuming the code sample you provided is meant to be a hash, and that the hash is assigned to the variable output, then there are possibly two ways of doing this but each has issues.

First, let's make clear that you're attempting to read output[:resource_title], which is an object of some class that has an instance variable @hostname that holds the value example.com, and that you want some way to read that hostname value.

output[:resource_title] is an instance of some class. Instances can have instance variables and in this case it has the instance variable @hostname. It's possible to read instance variables directly in Ruby but generally this is discouraged because if the author wanted users to be able to read that value then the author would have added a getter method to allow that value to be read.

We can't tell if there is a getter method there or not, so the easiest way to check is just to try accessing the method:

output[:resource_title].hostname

If this raises an error like NoMethodError: undefined method 'hostname' then there is no getter method and you need to read the instance variable directly. Even though it's discouraged, Ruby is flexible enough to make it pretty easy to do:

output[:resource_title].instance_variable_get('@hostname')
=> "example.com"

Comments

1

Assuming that data is in the variable output and there is a hostname accessor method on the object under the key :resource_title, then the code would be:

output[:resource_title].hostname

Comments

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.