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

try_over3_3.rbのQ5. チャレンジ問題!にtaskで定義したClass以外で呼び出すテストを追加 #45

Conversation

madogiwa0124
Copy link
Contributor

既存testだと下記のような実装(const_missingのsuperを呼び出してない)にした場合にTryOver3::A5Task::Bar.runといったtaskで定義していないようなClassを使った呼び出し方でも通ってしまったので、定義したClass以外はNameErrorが発生することを確認するtestを追加しました。

TryOver3 = Module.new
module TryOver3::TaskHelper
  def self.included(klass)
    klass.define_singleton_method :task do |name, &task_block|
      singleton_class.define_method(:run_task) do |const_name: '', deplicated: false|
        warn "Warning: #{self}::#{const_name}.run is duplicated" if deplicated
        puts "start #{Time.now}"
        block_return = task_block.call
        puts "finish #{Time.now}"
        block_return
      end
      private_class_method :run_task

      singleton_class.define_method(name) { run_task }
      singleton_class.define_method(:const_missing) do |const_name|
        new_klass_name = name.to_s.split("_").map{ |w| w[0] = w[0].upcase; w }.join
        # return super(const_name) if new_klass_name.to_sym != const_name # ここが無くても通る
        tap { |obj| obj.class.define_method(:run) { run_task(const_name: const_name, deplicated: true) } }
      end
    end
  end
end

class TryOver3::A5Task
  include TryOver3::TaskHelper

  task :foo do
    "foo"
  end
end

TryOver3::A5Task::Bar.run
Warning: TryOver3::A5Task::Bar.run is duplicated
start 2020-03-04 00:19:21 +0900
finish 2020-03-04 00:19:21 +0900
=> "foo"

既存だと下記のような実装にした場合に`TryOver3::A5Task::Bar.run`といった
taskで定義していないようなClassを使った呼び出し方でも通ってしまったので、
定義したClass以外はNameErrorが発生することを確認するtestを追加しました。

``` ruby
TryOver3 = Module.new
module TryOver3::TaskHelper
  def self.included(klass)
    klass.define_singleton_method :task do |name, &task_block|
      singleton_class.define_method(:run_task) do |const_name: '', deplicated: false|
        warn "Warning: #{self}::#{const_name}.run is duplicated" if deplicated
        puts "start #{Time.now}"
        block_return = task_block.call
        puts "finish #{Time.now}"
        block_return
      end
      private_class_method :run_task

      singleton_class.define_method(name) { run_task }
      singleton_class.define_method(:const_missing) do |const_name|
        new_klass_name = name.to_s.split("_").map{ |w| w[0] = w[0].upcase; w }.join
        # return super(const_name) if new_klass_name.to_sym != const_name # ここが無くても通る
        tap { |obj| obj.class.define_method(:run) { run_task(const_name: const_name, deplicated: true) } }
      end
    end
  end
end

class TryOver3::A5Task
  include TryOver3::TaskHelper

  task :foo do
    "foo"
  end
end

TryOver3::A5Task::Bar.run
Warning: TryOver3::A5Task::Bar.run is duplicated
start 2020-03-04 00:19:21 +0900
finish 2020-03-04 00:19:21 +0900
=> "foo"
```
@kinoppyd
Copy link
Owner

良いテストです、ありがとうございます!

@kinoppyd kinoppyd merged commit ba7e384 into kinoppyd:master Mar 13, 2020
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

Successfully merging this pull request may close these issues.

None yet

2 participants