Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
課題をテストで解決する
Search
shibayu36
April 20, 2014
Programming
2.5k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
課題をテストで解決する
shibayu36
April 20, 2014
More Decks by shibayu36
See All by shibayu36
非定型業務をAI slackbotで自動化する ~ 社内要望を自動壁打ちするbotを作った ~/automating-ad-hoc-work-with-ai-slackbot
shibayu36
0
750
顧客との商談議事録をみんなで読んで顧客解像度を上げよう
shibayu36
0
1k
QAフローを最適化し、品質水準を満たしながらリリースまでの期間を最短化する #RSGT2026
shibayu36
2
5.4k
EMこそClaude Codeでコード調査しよう
shibayu36
0
1.2k
詳しくない分野でのVibe Codingで困ったことと学び/vibe-coding-in-unfamiliar-area
shibayu36
3
5.9k
個人CLAUDE.md紹介と設定から学んだこと/introduce-my-claude-md
shibayu36
0
2k
今の生産性改善活動で大切にしている考え方
shibayu36
8
8.8k
エンジニアメンター制度の効果的な運用を目指して/improve-mentor-system
shibayu36
27
10k
グレードイメージ具体化のため昇格理由を公開する
shibayu36
8
6k
Other Decks in Programming
See All in Programming
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
800
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
1
300
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
200
The NotImplementedError Problem in Ruby
koic
1
920
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
1
110
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
12
6.1k
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
280
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
320
Claspは野良GASの夢をみるか
takter00
0
210
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
920
ふつうのFeature Flag実践入門
irof
8
4.2k
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
150
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
97
6.7k
The Limits of Empathy - UXLibs8
cassininazir
1
370
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Agile that works and the tools we love
rasmusluckow
331
22k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
170
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
66
55k
RailsConf 2023
tenderlove
30
1.5k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
210
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
240
What's in a price? How to price your products and services
michaelherold
247
13k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
Transcript
՝ΛςετͰղܾ͢Δ DevLOVEؔ 2014/04/19 shiba_yu36
ࣗݾհ
!TIJCB@ZV • ͯͳΞϓϦέʔγϣϯΤϯδχΞ • ͯͳϒϩάνʔϜ • PerlɺςετɺσϓϩΠɺ։ൃڥ
ϒϩά http://shibayu36.hatenablog.com/
ࠓͷ ͯͳϒϩάͷςετ ՝Λղܾ͢Δςετࣄྫ ՝ͱςετ
ͯͳϒϩάͷςετ
UFTUT UFTUTNP CVJMETEBZ NJOCVJME FOHJOFFST
Perlͷ୯ମςετ ;Δ·͍ςετ Model DB Controller View JavaScript lint ͦͷଞ crontab
nginx ઃఆ߲ syntax
ςετͷํ • શͯͷϝιουΛςετ • PerlҎ֎ͷ෦ • ՝ΛςετͰΧόʔ
ςετͷํ • શͯͷϝιουΛςετ • PerlҎ֎ͷ෦ • ՝ΛςετͰΧόʔ
՝ΛςετͰΧόʔʁ
՝ʁ ॻࣜϛε ༁Ε υΩϡϝϯτ σβΠφͱͷڠۀ ઃఆϛε
՝ʁ ॻࣜϛε ༁Ε υΩϡϝϯτ σβΠφͱͷڠۀ ઃఆϛε ਓ͕ؾΛ͚ͭΔ
ਓ͕ؾΛ͚ͭΔ ՝ʁ ॻࣜϛε ༁Ε υΩϡϝϯτ σβΠφͱͷڠۀ ઃఆϛε ςετͰΧόʔ
՝Λղܾ͢Δςετ
ݴޠʹΑΒͳ͍ ՝ͱςετ ݴޠʹΑΔ ୯ମςετ
՝1 crontabΛσϓϩΠͨ͠Β ಈ͔ͳ͔ͬͨ
• crontabͷॻࣜϛε • ࢦఆͨ͠ϑΝΠϧύεΛؒҧ͑Δ • ϩδοΫϛε -> ςετ͋ΔͷͰ΄ͱΜͲͳ͍ ݪҼ
ݪҼ • crontabͷॻࣜϛε • ࢦఆͨ͠ϑΝΠϧύεΛؒҧ͑Δ • ϩδοΫϛε -> ςετ͋ΔͷͰ΄ͱΜͲͳ͍ ਓ͕ؾΛ͚ͭΔ
ςετͰΧόʔ
ςετ͍ͨ͜͠ͱ
[email protected]
! 10 5 * * * apache perl /path/to/dir/script/echo.pl!
30 09 * * * apache perl /path/to/dir/script/sleep.pl
ςετ͍ͨ͜͠ͱ
[email protected]
! 10 5 * * * apache perl /path/to/dir/script/echo.pl!
30 09 * * * apache perl /path/to/dir/script/sleep.pl ϑΝΠϧऴʹվߦ͋Δ ࢦఆϑΝΠϧଘࡏ͢Δ ࢦఆਖ਼͍͠
ϑΝΠϧऴʹվߦ͋Δ? my $crontab = file('config/crontab')->slurp;! like $crontab, qr/\n$/, 'ϑΝΠϧඌʹվߦඞཁ'; ϑΝΠϧ༰Λ
ਖ਼نදݱͰνΣοΫ
ࢦఆϑΝΠϧଘࡏ͢Δ? my @files = $crontab =~ m{/path/to/dir/(.*\.pl)}g;! ! for my
$file (@files) {! ok -e $file, "$file ͕ଘࡏ";! }
ࢦఆϑΝΠϧଘࡏ͢Δ? my @files = $crontab =~ m{/path/to/dir/(.*\.pl)}g;! ! for my
$file (@files) {! ok -e $file, "$file ͕ଘࡏ";! } QSPKFDUͬΆ͍ϑΝΠϧ୳͢ ͦΕͧΕϑΝΠϧ͋Δ͔
ߋʹςετ͢Δ • crontabͷParser࣮Λ͏ • PerlͩͱParse::Crontab • ͷࢦఆϛεͱ͔νΣοΫͯ͘͠ΕΔ
গ͠ͷςετͰਓ͕ ؾΛ͚ͭΔඞཁແ͘ͳͬͨ
՝2 ઃఆϛεΛͯ͠ σϓϩΠͯ͠͠·ͬͨ
ΞϓϦέʔγϣϯͷઃఆ • ڥ͝ͱͷઃఆͱ͔ • DBʹ֨ೲ͢Δ·Ͱͳ͍σʔλ • etc
[! {! "blog_url" : "http://shibayu36.hatenablog.com/",! "permission" : "public",! "can_be_edited_by" :
[! "shiba_yu36"! ]! },! {! "blog_url" : "http://shibayu36-private.hatenablog.com/",! "permission" : "private",! "can_be_edited_by" : [! "shiba_yu36",! "shiba_yu37"! ]! },! {! "blog_url" : "http://blog.example.com/",! "permission" : "public",! "can_be_edited_by" : [! "example-user"! ]! }! ]
[! {! "blog_url" : "http://shibayu36.hatenablog.com/",! "permission" : "public",! "can_be_edited_by" :
[! "shiba_yu36"! ]! },! {! "blog_url" : "http://shibayu36-private.hatenablog.com/",! "permission" : "private",! "can_be_edited_by" : [! "shiba_yu36",! "shiba_yu37"! ]! },! {! "blog_url" : "http://blog.example.com/",! "permission" : "public",! "can_be_edited_by" : [! "example-user"! ]! }! ] CMPH@VSM63-Ͱ͋Δ
[! {! "blog_url" : "http://shibayu36.hatenablog.com/",! "permission" : "public",! "can_be_edited_by" :
[! "shiba_yu36"! ]! },! {! "blog_url" : "http://shibayu36-private.hatenablog.com/",! "permission" : "private",! "can_be_edited_by" : [! "shiba_yu36",! "shiba_yu37"! ]! },! {! "blog_url" : "http://blog.example.com/",! "permission" : "public",! "can_be_edited_by" : [! "example-user"! ]! }! ] QFSNJTTJPO QVCMJD͔QSJWBUF
[! {! "blog_url" : "http://shibayu36.hatenablog.com/",! "permission" : "public",! "can_be_edited_by" :
[! "shiba_yu36"! ]! },! {! "blog_url" : "http://shibayu36-private.hatenablog.com/",! "permission" : "private",! "can_be_edited_by" : [! "shiba_yu36",! "shiba_yu37"! ]! },! {! "blog_url" : "http://blog.example.com/",! "permission" : "public",! "can_be_edited_by" : [! "example-user"! ]! }! ] CMPH@VSM શମͰϢχʔΫ
Ͳ͏༷ͬͯΛ͑Δ? υΩϡϝϯτ ؾ͔ͮΕͳ͍ ϛεΛ͢Δ
͜Εςετʹͯ͠͠·͏
my $blogs_config = decode_json(file('blogs.json')->slurp);! ! for my $config (@$blogs_config) {!
! my $blog_url = URI->new($config->{blog_url});! is $blog_url->scheme, 'http', "blog_urlhttpͷURLͰ͋Δ";! ! cmp_deeply $config->{permission}, any('public', 'private'),! 'permissionpublic͔privateͰ͋Δ';! }
my $blogs_config = decode_json(file('blogs.json')->slurp);! ! for my $config (@$blogs_config) {!
! my $blog_url = URI->new($config->{blog_url});! is $blog_url->scheme, 'http', "blog_urlhttpͷURLͰ͋Δ";! ! cmp_deeply $config->{permission}, any('public', 'private'),! 'permissionpublic͔privateͰ͋Δ';! } CMPH@VSM63-Ͱ͋Δ QFSNJTTJPO QVCMJD͔QSJWBUF
CMPH@VSM શମͰϢχʔΫ my $blogs_config_uniq = [! uniq_by { $_->{blog_url} }
@$blogs_config,! ];! ! is scalar @$blogs_config_uniq,! scalar @$blogs_config,! "blog_url͕શମͰϢχʔΫͰ͋Δ";
υΩϡϝϯτ͔Βςετʹ • ؾ͔Εͳͯ͘ɺςετ͕མͪͯΒͤ ͯ͘ΕΔ • ϛε͕͋ͬͯςετͰݕ
IUUQTIJCBZVIBUFOBCMPHDPNFOUSZ ઃఆͷ༷ΛυΩϡϝϯτʹ ॻ͘ͷͰͳ͘ɺςετʹͯ͠͠·͏
ൃల • ઃఆͷΫϥεΛ࡞Δ • http://hitode909.hatenablog.com/entry/ 2014/04/10/114403
՝3 ༁ΛΕͯ σϓϩΠͯ͠͠·ͬͨ
ଟݴޠରԠͷΈ CMPHNBOBHF MPD bCMPHNBOBHF` ϒϩάཧ .BOBHF#MPH
<html>! <head>! <title>[% loc('blog.manage') %]</title>! </head>! <body>! <p>[% loc('blog.manage.description') %]</p>!
</body>! </html> <html>! <head>! <title>[% loc('blog.manage') %]</title>! </head>! <body>! <p>ϒϩάཧ͕Ͱ͖·͢</p>! </body>! </html>
Ͳ͏ͬͯݕ͢Δ͔ • Viewʹຊޠ͕ೖͬͯͳ͍͜ͱͷςετ • ຊਓͳͷͰɺେ͜ΕͰղܾͰ͖Δ
my @files = glob('templates/*.html');! ! for my $file (@files) {!
my $content = file($file)->slurp;! my $has_japanese = $content =~ /[^[:ascii:]]+/;! ok ! $has_japanese, "$file ຊޠΛؚ·ͳ͍";! } <html>! <head>! <title>[% loc('blog.manage') %]</title>! </head>! <body>! <p>ϒϩάཧ͕Ͱ͖·͢</p>! </body>! </html>
՝4 υΩϡϝϯτʹ ؾ͍ͮͯΒ͑ͳ͍
ରࡦ4 IUUQTIJCBZVIBUFOBCMPHDPNFOUSZ υΩϡϝϯτͷॴΛΒͤΔͨΊʹɺ མͪΔςετΛ࡞Δ
՝5 Nginxͷઃఆ͕ ϦϑΝΫλϦϯά͞Εͳ͍ ֬ೝ͕͍ͨ͠Ί
ରࡦ5 NginxΛҰ࣌తʹىಈͯ͠ ςετΛ͢Δ
IUUQTIJCBZVIBUFOBCMPHDPNFOUSZ nginxͷproxyઃఆϑΝΠϧ ࣗಈςετ͠Α͏
·ͱΊ
ػցʹΒͤΔ ਓ͕ؾΛ͚ͭΔ ՝ ྫ) ςετ
͍͜͠ͱͯ͠ͳ͍ ୯ମςετΑΓΉ͠Ζ؆୯
ςετ͍Ζ͍Ζ͋ͬͯ ࢝Ίํ͔Βͳ͍
ʑͷ՝ΛςετͰ ղܾ͢Δͱ͜Ζ͔Β͡ΊΔ