[Mac] Swiftで定数を宣言する

Swiftの定数は次のように宣言できます。

定数は 「let 定数名」で宣言できます。

let a = 10
let b = 0.1
let c = “abc”

「,」で区切って、複数の変数を宣言することも出来ます。

let d=20, e=0.2, f=”def”

型を指定せずに宣言した場合、宣言時に代入された値から推論して型が決められます。

String(a.dynamicType)
// => “Int”
String(b.dynamicType)
// => “Double”
String(c.dynamicType)
// => “String”

上記のように型を指定せずに宣言することもできますが、「let 定数名:型名」というように型を指定して宣言することもできます。

let g:Int = 10
let h:Double = 0.1
let i:String = “ghi”

変数と異なり、定数の値を変更しようとするエラーになります。

// c=”def”
// => Cannot assign to value: ‘c’ is a ‘let’ constant
// 定数の値を変更しようとしたためエラー

変数と同様に、型を指定せず値も代入しない場合は宣言することはできません。

// let j
// => Type annotation missing in pattern
// エラーになる

let k:Int
// これはOK

ここまでで宣言した定数にはnilを代入することはできません。

// k=nil
// => Nil cannot be assigned to type ‘Int’
// 通常の定数にはnilは代入できないのでエラーになる

nilを代入可能にするには、「let 変数名:型名?」と型名の後に?をつける必要があります。

let l:Int?
l=nil

オプショナル変数を通常の変数に戻す(アンラップ)するには「!」演算子を使用します。

let m:String? = “jkl”
print(m)
// => Optional(“jkl”)

//let n:String = m
// => Value of optional type ‘String?’ not unwrapped; did you mean to use ‘!’ or ‘?’?
// オプショナル定数は通常の定数に代入できないのでエラーになる。

let n:String = m!
// !演算子を使って通常の定数に戻す(アンラップ)と代入可能になります。

print(m!)
// => “jkl”
print(n)
// => “jkl”

[Mac] Swiftで変数を宣言する

Swiftの変数は次のように宣言できます。

変数は 「var 変数名」で宣言できます。

var a = 10
var b = 0.1
var c = “abc”

「,」で区切って、複数の変数を宣言することも出来ます。

var d=20, e=0.2, f=”def”

型を指定せずに宣言した場合、宣言時に代入された値から推論して型が決められます。

String(a.dynamicType)
// => “Int”
String(b.dynamicType)
// => “Double”
String(c.dynamicType)
// => “String”

上記のように型を指定せずに宣言することもできますが、「var 変数名:型名」というように型を指定して宣言することもできます。

var g:Int = 10
var h:Double = 0.1
var i:String = “ghi”

型が異なる変数に代入しようとするエラーになります。

// c=20
// => Cannot assign value of type ‘Int’ to type ‘String’
// String型の変数に整数を代入しようとしたためエラー

型を指定せず値も代入しない場合は、変数を宣言することはできません。

// var j
// => Type annotation missing in pattern
// エラーになる

var k:Int
// これはOK

ここまでで宣言した変数にはnilを代入することはできません。

// d=nil
// => Nil cannot be assigned to type ‘Int’
// 通常の変数にはnilは代入できないのでエラーになる

// print(k)
// => Variable ‘k’ used before being initialized
// 値が代入されてないためエラーになる

nilを代入可能にするには、「var 変数名:型名?」と型名の後に?をつけたオプショナル変数とする必要があります。

var l:Int?
print(l)
// => “nil”

l=30
print(l)
// => “Optional(30)\\n”
// オプショナル変数の場合、printすると「Optional(値)」と表示される。
l=nil
// オプショナル変数にはnilも代入可能

オプショナル変数を通常の変数に戻す(アンラップ)するには「!」演算子を使用します。

var m:String? = “jkl”
print(m)
// => Optional(“jkl”)

//var n:String = m
// => Value of optional type ‘String?’ not unwrapped; did you mean to use ‘!’ or ‘?’?
// オプショナル変数は通常の変数に代入できないのでエラーになる。

var n:String = m!
// !演算子を使って通常の変数に戻す(アンラップ)と代入可能になります。

print(m!)
// => “jkl”
print(n)
// => “jkl”

[Mac][Swift] オブジェクトの型(クラス名)を取得する

Swiftでは次の方法でオブジェクトの型を取得することができます。

var a = 10
var b = 0.1
var c = “abc”
a.dynamicType
// => Int.Type

.Typeが邪魔な場合はStringを使うと便利

String(b.dynamicType)
// => “Double”

print関数内では.Typeが付かず出力される

print(c.dynamicType)
// “String\n”

クラス名も取得できる。

class Test {
}
var test = Test()
print(test.dynamicType)
// => “Test\n”

[Mac] Swiftで関数名や行番号などを出力する

次のデバッグ用のリテラルを用いると、ファイル名や関数名などデバッグに役立つ情報を出力することが出来ます。

swift2までは、

print(“__FILE__ = \(__FILE__)”)
print(“__LINE__ = \(__LINE__)”)
print(“__COLUMN__ = \(__COLUMN__)”)
print(“__FUNCTION__ = \(__FUNCTION__)”)

上記のリテラルを使用できましたが、これらはswift3では廃止される予定らしく、実行すると

__FILE__ is deprecated and will be removed in Swift 3, please use #file
__LINE__ is deprecated and will be removed in Swift 3, please use #line
__COLUMN__ is deprecated and will be removed in Swift 3, please use #column
__FUNCTION__ is deprecated and will be removed in Swift 3, please use #function

このような警告が表示されます。そのため、今後は以下のリテラルを使用する必要があります。

print(“#file = \(#file)”)
print(“#line = \(#line)”)
print(“#column = \(#column)”)
print(“#function = \(#function)”)
  • #file : ソースファイルのファイルパス
  • #line : ファイル中の行番号
  • #column : 列番号(行の中で何文字目か)
  • #function : 関数名

[Mac] Swiftのリテラルについて

Swiftには次のようなリテラルがあります。

  • 数値
// 整数(10進数)
15

// 負の整数(10進数)
-15

// 2進数(10進数で15)
0b1111

// 8進数(10進数で15)
-0o17

// 16進数(10進数15)
0x0f

  • 数値の指数表記
// 10の累乗を表記する場合は「e」を使います。
// 15*10の3乗
15e3

// 2の累乗を表記する場合は「p」を使います。
// 0x0f(10進数の15)*2の3乗
0x0fp3

// 10進数に対して「p」を使うとエラーになります。
// 15p3
// Expected a digit after integer literal prefix

  • Boolean
true

false

  • 文字
// Character型にすることで、
// アルファベットでも日本語でも格納可能です。
let char1:Character = “a”
let char2:Character = “あ”

// ただし、文字なので2文字以上は格納できません。
// let char3:Character = “aあ”
// Cannot convert value of type ‘String’ to specified type ‘Character’

  • 文字列
// String型にすることで、複数の文字が格納可能です。
let str1:String = “123abc”
let str2:String = “123あいう”

  • 配列
// [要素1, 要素2, 要素3, …]のように「,」で区切って表記します。
let ary1:[Int] = [1,2,3]
let ary2:[String] = [“123”, “abc”, “あいう”]

  • 辞書
// [キー1:値1, キー2:値2, キー3:値3, …]のように、「キー:値」の組み合わせを「,」で区切って表記します。
let dic1:[String:Int] = [“abc”:1, “あいう”:2]
let dic2:[Int:String] = [1:”abc”, 2:”あいう”]

[Mac][Swift] print関数、NSLog関数の出力先を変更する

通常、print関数は標準出力に、NSLog関数やCFShow関数は標準エラー出力に文字列を出力します。

freopen関数を使って次のようにすると、これらの出力先をファイルに変更することができます。

import Foundation

print(“print function 1”)
NSLog(“NSLog function 1”)

var stdout_file = NSString(string: “~/Desktop/stdout.txt”).stringByExpandingTildeInPath
var stderr_file = NSString(string: “~/Desktop/stderr.txt”).stringByExpandingTildeInPath

_ = freopen(stdout_file, “w”, stdout)
_ = freopen(stderr_file, “w”, stderr)

print(“print function 2”)
NSLog(“NSLog function 2”)

この例では、print関数の出力先を~/Desktop/stdout.txtに、NSLog関数の出力先を~/Desktop/stderr.txtに変更しています。

[Mac] Finderに表示されないライブラリ(Library)フォルダ等を表示する

Macでは通常、アプリケーションが利用する設定情報など重要な情報は /Users/ユーザー名/Library に保存されてます。
しかし、このフォルダは重要なのでFinderからは通常見えなくなっています。

どこで可視/不可視を判別をしているかというと、各ファイル(フォルダ)にはchflagsというコマンドで設定できるフラグが設定されています。
これは以下のようにlsコマンドにOオプションをつけると確認できます。

$ ls -lO /Users/hoge/
total 0
drwx——+ 10 hoge staff – 340 5 13 01:08 Desktop
drwx——+ 33 hoge staff – 1122 2 27 02:19 Documents
drwx——+ 15 hoge staff – 510 5 16 16:12 Downloads
drwx——@ 61 hoge staff hidden 2074 5 17 09:57 Library
drwx——+ 3 hoge staff – 102 10 3 2015 Movies

グループ名の後ろにhiddenという表示が確認できると思います。このフラグをFinderが確認して非表示にしています。

これを取り除いてFinderに表示させるには次のコマンドを実行します。

$ chflags nohidden ~/Library

これで表示されているかと思います。

再度表示にするには次のように実行します。

$ chflags hidden ~/Library

[Mac] Finderで見えないファイルを表示する

Finderを使っていると「.(ドット)」で始まるUNIX特有の不可視ファイルやシステムが利用する重要なファイルなど、一部不可視設定になっているファイルがFinder上で表示されなくなっていると思います。

これらはターミナルからコマンドを使うとアクセスすることができますが、以下のコマンドを実行することでFinder上からも見えるようにすることができます。

$ defaults write com.apple.finder AppleShowAllFiles -bool true
$ killall Finder

元に戻すときは次のコマンドを実行します。

$ defaults delete com.apple.finder AppleShowAllFiles
$ killall Finder

まぁ、設定するのにターミナルが必要なので、だったらターミナルからアクセスすればいいじゃんって気がしなくもないですが、どうしてもFinderからアクセスする必要があれば設定してみてください。

SSHの環境変数を利用してiptablesのポートを解放する

安いVPSなどを借りて、普段はSSHだけ解放しといて、SSH以外のポートは自宅(社内)からのみアクセスできるようにしたいと思いました。

アクセス元のIPが固定であれば特に問題ないのですが、動的に割り当てられる環境だと毎回変わってしまうので、SSHの環境変数を利用して、SSHログイン後に実行するとフィルターが解除されるような次のスクリプトを作ってみました。

#!/bin/bash
IP=`env | grep SSH_CLIENT | sed ‘s/SSH_CLIENT=\([0-9\.]*\) .*/\1/’`
sudo sed -i’.old’ -e “/–dport 80/c\-A INPUT -m state –state NEW -m tcp -p tcp -s ${IP} –dport 80 -j ACCEPT” /etc/sysconfig/iptables
sudo service iptables restart

SSHでログインした後で実行すると、環境変数を参照して「–dport 80」の記述をログイン元のIPからのみHTTPを解放するように変更します。そのため、事前に「–dport 80」に関する何らかの記述がないとエラーになるかもしれません。

その他のポートも解放したければsedの行を増せば良いと思います。

[Ansible] さくらのVPSにCentOS6を再インストール

Ansibleを使って、さくらのVPSにCentOS6を最小パッケージで再インストールするroleです。

roles/sakura-install/tasks/main.yml

– include: kickstart.yml

roles/sakura-install/tasks/kickstart.yml

– name: Download vmlinuz
 get_url: url=”http://ftp.riken.jp/Linux/centos/6/os/x86_64/isolinux/vmlinuz” dest=/boot
 become: yes
 tags: install

– name: Download initrd.img
 get_url: url=”http://ftp.riken.jp/Linux/centos/6/os/x86_64/isolinux/initrd.img” dest=/boot
 tags: install

– name: Copy Kickstart file
 template: src={{ item.src }} dest={{ item.dst }}
 with_items:
 – src: ks.cfg.j2
 dst: /boot/ks.cfg
 tags: install

– name: Configure grub.conf
 lineinfile:
 dest: /etc/grub.conf
 line: “title CentOS 6 install
    root (hd0,0)
    kernel /vmlinuz ro root=LABEL=/ ks=hd:vda1:/ks.cfg
    initrd /initrd.img”
 tags: install

roles/sakura-install/templates/ks.cfg.j2

firewall –enabled –ssh –service=ssh
# Install OS instead of upgrade
install
# Use network installation
url –url=”http://ftp.riken.jp/Linux/centos/6/os/x86_64″
# Root password
rootpw {{ root_password }}
# System authorization information
auth –useshadow –passalgo=sha512
# Use text mode install
text
# System keyboard
keyboard jp106
# System language
lang en_US
# SELinux configuration
selinux –disabled
# Do not configure the X Window System
skipx
# Installation logging level
logging –level=info
# Reboot after installation
reboot
# System timezone
timezone Asia/Tokyo
# Network information
network –bootproto=static –device=eth0 –gateway={{ ansible_default_ipv4.gateway }} –ip={{ ansible_eth0.ipv4.address }} –nameserver={{ nameserver }} –netmask={{ ansible_eth0.ipv4.netmask }} –onboot=on –noipv6 –hostname {{ ansible_nodename }}
# System bootloader configuration
bootloader –append=”console=ttyS0,115200n8r crashkernel=auto” –location=mbr –driveorder=”vda”
# Partition clearing information
clearpart –all –drives=vda
# Disk partitioning information
part /boot –fstype=”ext4″ –size=500
part pv.00 –grow –size=1

volgroup vg_00 –pesize=4096 pv.00
logvol / –fstype=ext4 –name=lv_root –vgname=vg_00 –grow –size=1024 –maxsize=102400
logvol swap –name=lv_swap –vgname=vg_00 –grow –size=512 –maxsize=2048

%packages –nobase
@core

%end

ks.cfg.j2中にroot_passwordを変数で設定していますが、これはvars/main.ymlにべた書きするか、ansible-vaultコマンドで暗号化して保存しておいてください。

このroleを実行後に再起動すれば、自動的に再インストールが始まります。