✖
GetActersをクラスメソッドに
モブのクラス化
GetActersをクラスメソッドに
モブのクラス化
pcall とかいう安全な関数呼出なんていう関数があるんだけど、つかいにくい。
ok, err = pcall(function ()
end)
if not ok then exit endみたいな。
function try(tryFun)
local suc, err = pcall(tryFun)
return {
catch = function (catchFun)
if not suc then
catchFun(err)
end
end
}
end
try(function ()
print "hoge"
error("error")
end).catch(function (e)
print(e)
print "Catched"
end)とかやってみる。Io の try catch に似てる構造
できるだけ同じ名前を出さないという方向で書きかたを考えてみる。
#!/usr/bin/lua
List = {
new = function ()
return setmetatable({
-- instance variables
firstIndex = 0,
lastIndex = -1,
}, { __index = List.prototype })
end,
prototype = {
unshift = function (self, value)
self.firstIndex = self.firstIndex - 1
self[self.firstIndex] = value
return self
end,
push = function (self, value)
self.lastIndex = self.lastIndex + 1
self[self.lastIndex] = value
return self
end,
shift = function (self)
local first = self.firstIndex
if first > self.lastIndex then
return nil
end
local value = self[first]
self[first] = nil
self.firstIndex = first + 1
return value
end,
pop = function (self)
local last = self.lastIndex
if self.firstIndex > last then
return nil
end
local value = self[last]
self[last] = nil
self.lastIndex = last - 1
return value
end,
clear = function (self)
for i,v in ipairs(self) do
self[i] = nil
end
self.firstIndex = 0
self.lastIndex = -1
end,
size = function (self)
return self.lastIndex - self.firstIndex + 1
end,
first = function (self)
return self[self.firstIndex]
end,
last = function (self)
return self[self.lastIndex]
end,
},
}
l = List.new()
print(l)
-- basic tests
l:push(1)
l:push(2)
assert(l:pop() == 2)
assert(l:pop() == 1)
l:push(1)
l:unshift(2)
assert(l:size() == 2)
assert(l:first() == 2)
assert(l:last() == 1)
assert(l:shift() == 2)
assert(l:shift() == 1)
assert(l:size() == 0)
l:push(1)
assert(l:size() == 1)
l:clear()
assert(l:size() == 0)
-- multi-obj tests
l1 = List.new()
l1:push(1)
l:push(1)
l1:push(2)
l:push(2)
assert(l1:pop() == 2)
assert(l:pop() == 2)
assert(l1:pop() == 1)
assert(l:pop() == 1)
-- prototype 書きかえてみる
List.prototype.hoge = function ()
return "hoge"
end
assert(l:hoge() == "hoge")
-- プロトタイプとってきたいとき
assert(getmetatable(l).__index == List.prototype)
print "Tests are completed"new の中ででてきてしまう。うーん。
Lua は基本的にオブジェクト指向がどうこうっていう話はあんまりなくて、テーブルとメタテーブルをごにょって自分でやるらしい。
あるテーブルはメタテーブルを持てて (そしてメタテーブルもまたテーブルなので、さらにメタテーブルを持てるはず?)、そのメタテーブルに定義された __hoge なキーの値が特別な意味をもってたりする (演算子のオーバーロードもこれでやるみたい。ためしてない)。__index キーには元のテーブルでキーが見付からないときに使われるテーブルをセットする。
self を暗黙的に使うシンタックスもあるけど、名前が何回もでてきてうざくなる。
function Class(obj)
-- metatable も __index も同じにする (再帰参照)
-- 演算子オーバーロードも直感的に書けるように
obj.__index = obj
-- superclass の設定
setmetatable(obj, { __index = obj.super})
return setmetatable({
new = function(...)
local newObj = {}
setmetatable(newObj, obj)
newObj:initialize(unpack(arg))
return newObj
end
}, obj)
end
List = Class { super = nil,
__tostring = function ()
return "#<Class List>"
end,
initialize = function (self, ...)
self.firstIndex = 0
self.lastIndex = -1
for i,v in ipairs(arg) do self:push(v) end
end,
unshift = function (self, value)
self.firstIndex = self.firstIndex - 1
self[self.firstIndex] = value
return self
end,
push = function (self, value)
self.lastIndex = self.lastIndex + 1
self[self.lastIndex] = value
return self
end,
shift = function (self)
local first = self.firstIndex
if first > self.lastIndex then
return nil
end
local value = self[first]
self[first] = nil
self.firstIndex = first + 1
return value
end,
pop = function (self)
local last = self.lastIndex
if self.firstIndex > last then
return nil
end
local value = self[last]
self[last] = nil
self.lastIndex = last - 1
return value
end,
clear = function (self)
for i,v in ipairs(self) do
self[i] = nil
end
self.firstIndex = 0
self.lastIndex = -1
end,
size = function (self)
return self.lastIndex - self.firstIndex + 1
end,
first = function (self)
return self[self.firstIndex]
end,
last = function (self)
return self[self.lastIndex]
end,
}
l = List.new()
print(l)
-- basic tests
l:push(1)
l:push(2)
assert(l:pop() == 2)
assert(l:pop() == 1)
l:push(1)
l:unshift(2)
assert(l:size() == 2)
assert(l:first() == 2)
assert(l:last() == 1)
assert(l:shift() == 2)
assert(l:shift() == 1)
assert(l:size() == 0)
l:push(1)
assert(l:size() == 1)
l:clear()
assert(l:size() == 0)
-- multi-obj tests
l1 = List.new()
l1:push(1)
l:push(1)
l1:push(2)
l:push(2)
assert(l1:pop() == 2)
assert(l:pop() == 2)
assert(l1:pop() == 1)
assert(l:pop() == 1)
l2 = List.new(1, 2, 3, 4, 5)
assert(l2:pop() == 5)
assert(l2:pop() == 4)
assert(l2:shift() == 1)
assert(l2:shift() == 2)
assert(l2:pop() == 3)
-- prototype 書きかえてみる
getmetatable(l).hoge = function ()
return "hoge"
end
assert(l:hoge() == "hoge")
List2 = Class { super = List,
__tostring = function ()
return "#<Class List2>"
end,
initialize = function (self, values)
self.super.initialize(self, values)
end,
test = function (self, str)
print(str)
self:push(str)
end
}
l2 = List2.new()
print(l2)
l2:test("hoe")
l2:push(1)
l2:push(2)
assert(l2:pop() == 2)
assert(l2:pop() == 1)
print "Tests are completed"どうだろ
Bluetooth マウス欲しい。
Good Dog Happy Men は良いなぁ……
彼らはたぶん夏バンドだから、これからもっと良くなるに違いない。
#!/usr/bin/ruby
require "rubygems"
require "exifr"
require "pathname"
Pathname.glob("*.{jpg,JPG}") do |f|
date = EXIFR::JPEG.new(f.to_s).date_time_original
path = Pathname.new(date.strftime("%Y/%m%d"))
path.mkpath
f.rename(path + f)
puts "#{f} -> #{path}"
raw = Pathname.new(f.to_s.sub(/jpg$/i, "CR2"))
if raw.exist?
puts "#{raw} -> #{path}"
raw.rename(path + raw)
end
end