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

Scientist::Experiment.new creates Scientist::Default instance even when it should have been overridden #92

Open
mermop opened this issue Oct 19, 2018 · 5 comments

Comments

@mermop
Copy link

mermop commented Oct 19, 2018

Hi friends! Thank you for your great work with this gem ✨

I am having a problem in Rails apps where Scientist::Experiment defaults to the original Default object until the custom one is called - leading to some head-scratching about why the try block is not running even when enabled? is set to true.

I'm unsure whether this is a problem with the Rails load order because of how I've arranged my files, whether the examples in the README could be a little better, or whether there's genuinely a bug here.

$ bundle exec rails console
Loading development environment (Rails 5.1.6)
irb(main):001:0> Scientist::Experiment.new "something"
=> #<Scientist::Default:0x00007fd667bbcd40 @name="something">
irb(main):002:0> LdapExperiment.new(name: "something")
=> #<LdapExperiment:0x00007fd667b6ee10 @name="something">
irb(main):003:0> Scientist::Experiment.new "something"
=> #<LdapExperiment:0x00007fd667b34968 @name="something">

I've followed the instructions in the README, which are delightful and comprehensive.

# app/experiments/ldap_experiment.rb
require "scientist/experiment"

class LdapExperiment
  include Scientist::Experiment

  attr_accessor :name

  def initialize(name:)
    @name = name
  end

  def enabled?
    # ...
  end

  def publish(result)
    # ...
  end
end

module Scientist::Experiment
  def self.new(name)
    LdapExperiment.new(name: name)
  end
end
# app/models/whatever.rb
class Whatever
  include Scientist
  def do_something
    science "role lookup" do |e|
      e.use { do_one_thing }
      e.try { do_some_other_thing }
    end
  end
end

This is occurring in Rails 3.2.x and Rails 5.1.x applications, with version 1.2.0 of the gem.

@mermop mermop changed the title Scientist::Experiment.new creates Scientist::Default instance even when it should have been overridden Scientist::Experiment.new creates Scientist::Default instance even when it should have been overridden Oct 19, 2018
@mermop
Copy link
Author

mermop commented Oct 19, 2018

For the moment I've moved this block of code into an initializer:

module Scientist::Experiment
  def self.new(name)
    LdapExperiment.new(name: name)
  end
end

Which seems to work, so maybe it's just worth noting that strategy in the README

@benterprise
Copy link

I also ran into this problem and got around it by using the initializer above

@Linuus
Copy link

Linuus commented Sep 5, 2019

Super late response but maybe it helps someone else :)

Rails lazy loads classes in development. So, your experiment file has not been loaded yet and thus, the default experiment has not been overridden. That's why it works after you instantiate your experiment once which forces Rails to load the file.

@myhandisout
Copy link

Hi friends! Thank you for your great work with this gem ✨

I am having a problem in Rails apps where Scientist::Experiment defaults to the original Default object until the custom one is called - leading to some head-scratching about why the try block is not running even when enabled? is set to true.

I'm unsure whether this is a problem with the Rails load order because of how I've arranged my files, whether the examples in the README could be a little better, or whether there's genuinely a bug here.

$ bundle exec rails console
Loading development environment (Rails 5.1.6)
irb(main):001:0> Scientist::Experiment.new "something"
=> #<Scientist::Default:0x00007fd667bbcd40 @name="something">
irb(main):002:0> LdapExperiment.new(name: "something")
=> #<LdapExperiment:0x00007fd667b6ee10 @name="something">
irb(main):003:0> Scientist::Experiment.new "something"
=> #<LdapExperiment:0x00007fd667b34968 @name="something">

I've followed the instructions in the README, which are delightful and comprehensive.

# app/experiments/ldap_experiment.rb
require "scientist/experiment"

class LdapExperiment
  include Scientist::Experiment

  attr_accessor :name

  def initialize(name:)
    @name = name
  end

  def enabled?
    # ...
  end

  def publish(result)
    # ...
  end
end

module Scientist::Experiment
  def self.new(name)
    LdapExperiment.new(name: name)
  end
end
# app/models/whatever.rb
class Whatever
  include Scientist
  def do_something
    science "role lookup" do |e|
      e.use { do_one_thing }
      e.try { do_some_other_thing }
    end
  end
end

This is occurring in Rails 3.2.x and Rails 5.1.x applications, with version 1.2.0 of the gem.

@benoittgt
Copy link

benoittgt commented Feb 28, 2023

I did that, and it's ugly

class User < ApplicationRecord

  # Force loading of class otherwise `scientist` load the default
  # experiment class which is not what we want
  DefaultExperiment # our custom class that is enabled withe proper result
  extend Scientist # because it is on class method

end

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

5 participants