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

When requiring the Ruby's timeout library I can no longer retrieve a nested attribute named timeout on an OpenStruct #56

Open
burtlo opened this issue Mar 23, 2018 · 3 comments

Comments

@burtlo
Copy link

burtlo commented Mar 23, 2018

The wrapper class here is a quick example of the behavior. While the example does not use the timeout library methods it is present in a larger project I am currently working on.

Given this yaml file:

default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

And a test file:

require 'ostruct'
require 'yaml'
require 'timeout'
require 'rspec/its'

class DatabaseConfg
  def development
    hash = YAML.load(File.read('database.yml'))
    struct = OpenStruct.new(hash['development'])
  end
end

describe DatabaseConfg do
  its('development.database') { should eq 'db/development.sqlite3' }
  its('development.timeout') { should eq 5000 }
end

When I execute the tests I see an error that is the same error if you ran timeout without any parameters

$ rspec example_spec.rb
./usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rspec-its-1.2.0/lib/rspec/its.rb:115:in `block (3 levels) in its': Object#timeout is deprecated, use Timeout.timeout instead.
F

Failures:

  1) DatabaseConfg development.timeout
     Failure/Error: its('development.timeout') { should eq 5000 }

     ArgumentError:
       wrong number of arguments (given 0, expected 1..3)
     # ./rspec_example_spec.rb:15:in `block (2 levels) in <top (required)>'

Finished in 0.00413 seconds (files took 0.13378 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./rspec_example_spec.rb:15 # DatabaseConfg development.timeout
@burtlo burtlo changed the title When requiring the Ruby's timeout library I can no longer retrieve a nested attribute named timeout When requiring the Ruby's timeout library I can no longer retrieve a nested attribute named timeout on an OpenStruct Mar 23, 2018
@burtlo
Copy link
Author

burtlo commented Mar 23, 2018

I tried this with a Hashie::Mash and run into the same issue. If I recall correctly these libraries do not define the methods but instead rely on method_missing to proxy the request or dynamically generate the method and proxy the request.

To workaround it, I created a timeout method on the instance itself.

obj = Hashie::Mash.new(@yaml['development'])
def obj.timeout
  self['timeout']
end

@JonRowe
Copy link
Member

JonRowe commented Jan 10, 2019

Confirmed, theres some weirdness in method definition when theres two defined.

@pirj
Copy link
Member

pirj commented May 16, 2019

It seems that require 'timeout' is monkey patching BasicObject and injects .timeout.
To confirm that, you can call development.send(:timeout), you'll get a

warning: Object#timeout is deprecated, use Timeout.timeout instead.

in addition to an ArgumentError exception because you're not passing the timeout in seconds.

Related to #28.

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

No branches or pull requests

3 participants