開発時のみ実行するコードを実現するマクロ
微妙に objc の時と変わった。 毎回、手でやるのがたいへんな画面操作を、自動でやりたいときなどに、この中に組み込んでいたりする。
#if DEBUG // こんなかんじで、 画面遷移を自動でさせちゃう。 let vc = EntryViewController.instantiateFromStoryboard() vc.entry = self.entryList[0] self.navigationController?.pushViewController(vc, animated: true) #endif
swiftのコピペコード置き場
UILabel
- 開発中のデバッグでたまにコードで置いちゃう。
let label = UILabel.init(frame: CGRectMake(0, 100, 0, 0)) label.text = "Test Label" label.sizeToFit() view.addSubview(label)
イニシャライザの UILabel.init(frame: frame)
は UILabel(frame: frame)
とも書ける。
個人的には, objc っぽい見た目なので init がある前者のほうがすき。
あと、手早く書きたいならば let label:UIlabel ではなく、 let label = ... と書いちゃって、型推論に任せる。
せっかくあるものだから使っていかないと。
UIButton
let btn = UIButton.init(type: .System) btn.frame.origin.y = 150 btn.setTitle("button", forState: .Normal) btn.sizeToFit() btn.addTarget(self, action: "buttonPushed:", forControlEvents: .TouchUpInside) view.addSubview(btn) // MARK: - Controll Actions func buttonPushed(sender: UIButton){ print( "buttonn pushed" ) }
Swift になって、 btn.frame.origin.y = 150
みたいに直接座標を指定できるようになったの便利。
Pragma Mark
// MARK: - Controll Actions
Swift で enumを定義する
以下のように enum で環境を定義して、そこにAPIのBase URLを持たせることをよくする。
enum Env: Int { case Local case Staging case Production func baseURL() -> String { switch(self) { case .Local: return "http://localhost:3000" case .Staging: return "http://stg.hoge.com" case .Production: return "http://hoge.com" } } func description() -> String { switch(self) { case .Local: return "Local" case .Staging: return "Staging" case .Production: return "Production" } } }
enum から Int 型への変換は以下の通り rawValue
というメソッドを使う。
Env.Local.rawValue
swiftでテーブルビューの delegate と datasource を書く
// MARK: - UITableViewDelegate func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { tableView.deselectRowAtIndexPath(indexPath, animated: true) } // MARK: - UITableViewDataSource func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 } func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return 50 } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = UITableViewCell.init() cell.textLabel?.text = "cell\( String(indexPath.row) )" return cell }
■
今日は rake db 系のコードを読んでみた。 いつもお世話になっているコマンドなので, 内部の処理をあまり理解せずに使っていることに違和感を感じていた。 とくにいくつか,名前がにていて何が異なるのかがわからないコマンドがいくつかあった。
rake db 系のコマンドは以下で定義されている。
/activerecord/lib/activerecord/tasks/database.rake
気になったコマンドをいくつか見てみた。
rake db:migrate:reset
drop, create, migrate をまとめてやる。
desc がコメントアウトされていて -T で表示されないようになっている。 理由はわからない。
# desc 'Resets your database using your migrations for the current environment' task :reset => ['db:drop', 'db:create', 'db:migrate']
rake db:reset
drop, reset をする。 db/schema.rb から復元する。 seeds の読み込みも行う。 (とコメントに書いてある。)
# desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.' task :reset => [:environment, :load_config] do db_namespace["drop"].invoke db_namespace["setup"].invoke end
次にrake db コマンドの実行からどのようにDB操作の処理が行われているのかを追ってみた
Railsは MySQL, PostgreSQL, SQLite に対応しているので, database.rb にある設定を読み込んで 各 DB に対応する DB操作を行うクラスを選択している。 この処理は gems/activerecord-4.2.3/lib/active_record/tasks/database_tasks.rbにある register_task が行っている。
ActiveRecord::Tasks::DatabaseTasks が include された時点で, MySQL, PostgreSLQ, SQLite のタスクとキーのペアが登録される。
def register_task(pattern, task) @tasks ||= {} @tasks[pattern] = task end register_task(/mysql/, ActiveRecord::Tasks::MySQLDatabaseTasks) register_task(/postgresql/, ActiveRecord::Tasks::PostgreSQLDatabaseTasks) register_task(/sqlite/, ActiveRecord::Tasks::SQLiteDatabaseTasks)
class_for_adapter メソッドが, DBアダプタから, そのDBに対する ActiveRecord::Tasks を返す。 class_for_adapter の内部処理的には, adapter 引数で指定した DBタイプが @tasks にキーとしてあるかを確認して あれば, そのキーを返すという処理をしている。 detect を使っているのは 正規表現でマッチングさせたいからだと思う。 Array#detect メソッドは Array#find のエイリアス。
def class_for_adapter(adapter) key = @tasks.keys.detect { |pattern| adapter[pattern] } unless key raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter" end @tasks[key] end
database_configuration メソッドは database.yaml を読み込むメソッドで railties-4.2.3/lib/rails/application/configuration.rb にある。
単純に yaml をパースしてオブジェクトを返すようだが, なぜ ERB.new しているのかはまだ調べ切れていない。
# Loads and returns the entire raw configuration of database from # values stored in `config/database.yml`. def database_configuration path = paths["config/database"].existent.first yaml = Pathname.new(path) if path config = if yaml && yaml.exist? require "yaml" require "erb" YAML.load(ERB.new(yaml.read).result) || {} elsif ENV['DATABASE_URL'] # Value from ENV['DATABASE_URL'] is set to default database connection # by Active Record. {} else raise "Could not load database configuration. No such file - #{paths["config/database"].instance_variable_get(:@paths)}" end config rescue Psych::SyntaxError => e raise "YAML syntax error occurred while parsing #{paths["config/database"].first}. " \ "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \ "Error: #{e.message}" rescue => e raise e, "Cannot load `Rails.application.database_configuration`:\n#{e.message}", e.backtrace end