最近, 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_option
method_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.