最近, macOSでマウスカーソルがウィンドウにくっついてしまう現象が生じた. 以降の操作が何もできなくなってしまうのでとても困る. 環境は以下の通りである:
- macOS High Sierra 10.13.6
これとは別のケースで, ウィンドウがアクティブにならなくなってしまう現象は前から稀に起きていた. これら2つの不具合の対処方法を示す.
Thor::Group, Thor::Actions そしてERBテンプレート群とを組み合わせれば, これをとても簡単に実現できる (訳注: Thorはもともとrakeやsakeの代替えとして開発されていたようだ. ). ここに例を示そう:Thor::Group,Thor::Actions and ERB templates makes this very easy. Here is an example:class Newgem < Thor::Group
include Thor::Actions
# もろもろの引数とオプションを定義する
# Define arguments and options
argument :name
class_option :test_framework, :default => :test_unit
def self.source_root
File.dirname(__FILE__)
end
def create_lib_file
template('templates/newgem.tt', "#{name}/lib/#{name}.rb")
end
def create_test_file
test = options[:test_framework] == "rspec" ? :spec : :test
create_file "#{name}/#{test}/#{name}_#{test}.rb"
end
def copy_licence
if yes?("Use MIT license?")
# source rootディレクトリでMITLICENSEファイルをコピーする
# Make a copy of the MITLICENSE file at the source root
copy_file "MITLICENSE", "#{name}/MITLICENSE"
else
say "Shame on you…", :red
end
end
end
thor -T を実行すると, このジェネレータの使い方を表示する. それは thor newgem NAME を読むはずだ. これはジェネレータを実行するのに, われわれはNAMEという引数を与えなければならないことを示している.thor -T will show how to run our generator. It should read:thor newgem NAME. This shows that we have to supply a NAMEcreate_lib_file はERBテンプレートのひとつを使っている. これはこのようになる:create_lib_file uses an ERB template. This is what it looks like:class <%= name.capitalize %>
end
template が呼び出されたときに, 自動で渡される. その他のオプション詳細は ドキュメント を読んで確認せよ.template gets called. Be sure to read the documentation for more options.thor newgem devise で実行すると, ふたつのファイルが作られる: “devise/lib/devise.rb” と “devise/test/devise_test.rb” だ. その次にユーザは, (yes? メソッドを使ったプロンプトで) MITライセンスのファイルをコピーしたいかどうかたずねられる.thor newgem devise --test-framework=rspec のように追加できる. これはふたつのファイル: “devise/lib/devise.rb” と “devise/spec/devise_spec.rb” を生成する.thor newgem devise will create two files: “devise/lib/devise.rb”, and “devise/test/devise_test.rb”. The user will then be asked (via a prompt by the yes? method) whether or not they would like to copy the MIT License. If you want to change the test framework, you can add the option: thor newgem devise --test-framework=rspec.#! で始まる実行スクリプトの最初の一行目) を入れる.require "thor" する.#{YourThorClassname}.start を最下行に書く (訳注: .start(ary)とすると明示的に渡せる. この例のようにaryを指定しないとARGVが自動で使われる).#{YourThorClassname}.start to the bottom of your script.#!/usr/bin/env ruby
require "rubygems" # ruby1.9 doesn't "require" it though
require "thor"
class MyThorCommand < Thor
desc "foo", "Prints foo"
def foo
puts "foo"
end
end
MyThorCommand.start
chmod a+x mythorcommand.rb
./mythorcommand.rb foo
class App < Thor
desc 'install', 'Install something'
def install
# task code
end
# other tasks
end
thor app:install
module Sinatra
class App < Thor
desc 'install', 'Install something'
def install
# task code
end
# other tasks
end
end
thor sinatra:app:install
module Sinatra
class App < Thor
namespace :myapp
def install
# task code
end
# other tasks
end
end
thor myapp:install
say, ask, yes?, no?, add_file, remove_file, copy_file, template, directory, inside, run, inject_into_file や, その他にも2,3ある.say, ask, yes?, no?, add_file, remove_file, copy_file, template, directory, inside, run, inject_into_file and a couple more.Thor::Actions をincludeするだけだ:Thor::Actions in your Thor classes:class App < Thor
include Thor::Actions
# tasks
end
source_root と呼ばれる, クラスメソッドがひとつ必要となるアクションもある. このクラスメソッドはあなたのテンプレートたちが配置されているべきディレクトリだ. Thor::Actions と Thor::Shell::Basic のドキュメントを確認すること. たとえば:source_root be defined in your class. This is the directory where your templates should be placed. Be sure to check the documentation on Thor::Actions and Thor::Shell::Basic. For instance:class App < Thor
include Thor::Actions
def self.source_root
File.dirname(__FILE__)
end
end
Thor::Group という特別なクラスがある. ひとつの Thor::Group に 定義されたもろもろのタスクはすべて, それらが定義された順に, ひとつのシーケンスとして実行される. [[実行 Invocations]] で使った例は Thor::Group を使って, このように書ける:Thor::Group. All of the tasks defined in a Thor::Group are invoked together as a sequence, in the order that they were defined. The example from [[Invocations]] could be rewritten usingThor::Group as:require 'thor/group'
module MyAwesomeGem # 訳注: 名前空間のためのmodule
class MyCounter < Thor::Group # 訳注: ThorではなくThor::Group
desc "Prints 1 2 3"
def one
puts 1
end
def two
puts 2
end
def three
puts 3
end
end
end
thor my_awesome_gem:my_counter
# prints "1 2 3"
#!/usr/bin/env ruby
require File.expand_path('lib/command', Dir.pwd)
MyAwesomeGem::MyCommand.start
require "thor"
module MyAwesomeGem
class MyCommand < Thor
desc "foo", "Prints foo"
def foo
puts "foo"
end
end
end
cd myawesomegem
chmod a+x bin/command # make permission
bin/command foo
MyCounter を サブコマンドとして 使えるようにするには, Thor.registerメソッド をコールする必要がある:MyCounter available as a subcommand, you need to call the register method: require "thor"
require File.expand_path("lib/mycounter_file", Dir.pwd)
module MyAwesomeGem
class MyCommand < Thor
desc "foo", "Prints foo"
def foo
puts "foo"
end
# register(class_name, subcommand_alias, usage_list_string, description_string)
register(MyAwesomeGem::MyCounter, "counter", "counter", "Prints some numbers in sequence")
end
end
MyAwesomeGem::MyCounter < Thor::Group は, mycommand の中のサブタスクとして現れ, そのエイリアスは counter となり, 使い方は:MyCounter < Thor::Group will appear as a sub-task within mycommand with the alias counter, usage: bin/command
# Commands:
# command counter # Prints numbers in sequence
# command foo # Prints foo
bin/command counter
#=> 1 2 3
Thor::Group を使う場合は, あなたが (descメソッドで) 用意した説明書きは, それぞれのタスク毎にひとつの説明が用意されるのではなく, クラスそのものの説明書きとなる.Thor::Group, the description you provide (using the method desc) is for the entire class, as opposed to providing a description for each task.Thor::Group はもろもろの引数 arguments とオプションをThorのタスクとしてパースできる:Thor::Group can parse arguments and options as Thor tasks:class Counter < Thor::Group
# number will be available as attr_accessor
argument :number, :type => :numeric, :desc => "The number to start counting"
desc "Prints the 'number' given upto 'number+2'"
def one
puts number + 0
end
def two
puts number + 1
end
def three
puts number + 2
end
end
thor counter 5
# Prints "5 6 7"
thor counter 11
# Prints "11 12 13"
Thor::Group に与えることができるが, method_option と method_options の代わりに, class_option と class_options を使ってもいい. argument メソッドと class_optionsメソッドは両方とも, Thorクラスにも使用可能だ.Thor::Group, but instead of using method_optionmethod_options, you should use class_option and class_options.class_options methods are available to Thor class as well.Thor::Group は, 定義された順に実行される5,6個のステップで定義できるので, ジェネレータを作るのにすぐれたツールのひとつだ (Thor::Group は Rails 4.x のジェネレータに使われているツールだ. 訳注: Rails 5.xでもジェネレータとして使われている痕跡が残っている)Thor::Group is a great tool to create generators, since you can define several steps which are invoked in the order they are defined (Thor::Group is the tool used for generators in Rails 4.x).class Counter < Thor
desc "one", "Prints 1 2 3"
def one
puts 1
invoke :two # 訳注: タスクtwoの中のthreeは実行されない!
invoke :three
end
desc "two", "Prints 2 3"
def two
puts 2
invoke :three
end
desc "three", "Prints 3"
def three
puts 3
end
end
thor counter:one
1
2
3
three は一度だけ実行されるということだ. 他のクラスからでも, この機能を使ったタスクの実行はできるので, Thorクラスについて ドキュメント を確認すること.three task was invoked only once.one を実行するために Counter を一度インスタンス化し, その次に, タスク two の実行にもうひとつ, タスク three を実行するためにまたひとつ Counter をインスタンス化する. このことはもろもろのオプションと引数を, もう一度パースし直すことができるということだ. たとえば, もし two と three がそれぞれ異なったもろもろのオプションを持ち, 両方のオプション群がコマンドラインに与えられたような場合, invoke をコールすることで, それぞれのタスクに従って, タスク毎に毎回それらがパースされ, 使用される.Counter once to invoke the task one, then, it instantiates another to invoke the task two and another for task three. This allows options and arguments to be parsed again. For example, if two and three have different options and both of them were given to the command line, calling invoke enables them to be parsed each time and used accordingly by each task.