Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command.
Xcodeを最新にアップデートしたあとに、git
コマンドを叩いたら、下記のような表示が出た
Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command.
テキストの通り、
sudo xcodebuild -license
と、打っても良さそうだったが、自分の場合はXcode立ち上げて、出てきたライセンス表示に対してAgreeすることで問題なく通過した。
よく遭遇する表示のようだったが、自分はあんまり記憶になったので一応メモしておく。
(たぶん忘れているだけかも)
ステインド、かっこよい
初めて聴いた。
ニルヴァーナを始めとするUSオルタナを感じさせる殺気立ちながらもどこかメロディックなヴォーカルラインと、メランコリックでダークでヘヴィなハードロックという感じでかっこよかった!
CircleCIでdocker imageのバージョンを上げたときに、default-mysql-clientのインストールでエラーになった際の対応備忘録
CircleCI
で使用しているDocker image
のバージョンを上げたら、default-mysql-client
をインストールする箇所でエラーになりました。
最初色々とネットの記事を見ながら、何度か試行錯誤しつつ悩んでいましたが、CircleCI
で提供されている Docker Image
をローカルにpull
して、実際に動かしている CircleCI
の設定と照らし合わせながら手作業でデバッグ・実行してみることで問題はすぐに解決しました。
ちなみに私がぶち当たった問題の対応としては、default-mysql-client
のインストールコマンドを実行する前にsudo apt-get update
を行えばよいだけでした。
CircleCIが提供しているDocker Image
下記のリンク先で確認できます。
https://hub.docker.com/u/circleci
例えば下記のような形で試せます。
(下の例ではnode
のDocker image
をpull
しています)
docker pull circleci/node:{試したいversion} docker run -t -i {pullしてきたIMAGE ID} /bin/bash
あとはdockerコンテナの中で実際にコマンドを叩きながら、試していけばOK
また、geohotが面白そうな動画を出していた。checkm8を用いて、iPhoneをハックする(書きかけポスト)
本題の前に、イバラキングのごじゃっぺラジオZについて
昨日の放送を聞いていただいた皆様、ありがとうございました!
twitter
のハッシュタグ、#gojaradi
でも感想を色々呟いていただけて、とても嬉しかったです。
また、イバラキングさんのページでも紹介していただいています。嬉しい!
ここに写っている写真は、公開収録日に撮影されたもの📷
ラヂオでも話したとおり、現在はイバラキングさんとのコラボ曲や、アルバムに向けた楽曲制作をガンガン進めております。
実は今日もB/Wメンツでレコーディングをしていました。
完成したら報告させてもらうのでぜひぜひ聴いてください😊
geohotがcheckm8を用いて、iPhoneをハックする,,,らしい?(書きかけポスト)
話は変わり、、、
geohotこと、George Hotzが新しい動画を公開していた。
checkm8
を用いて、iPhoneをハックする動画のようだ。
(私はまだこの動画を見ていないので、動画の概要や飛ばし飛ばしで動画を見てこれを書いている。誤っていたら修正する)
checkm8
については、WIREDやEngadgetの記事などを読んで概要を理解した。
そういえば数日前にiPhoneのジェイルブレイク関連の記事を目にしていたなーと思いつつ、あまり気にせず通り過ぎてしまっていたが、これのことだったのか。
WIREDの記事を引用させてもらう。
セキュリティ研究者のaxi0mXが「Github」に公開したエクスプロイトコードは、「checkm8」と呼ばれる。このコードは、アップルの独自チップである「A5」から「A11」までのチップセットを搭載したすべてのアップル端末、つまり「iPhone 4S」から「iPhone X」にいたるまでのiPhone全モデルに影響する。
実際にGeorge Hotzの動画や、WIREDの記事でも書かれているセキュリティ研究者のaxi0mXが「Github」に公開したエクスプロイトコード
というのは下記になる。
このポストは書きかけのため、geohotの動画を見た段階で修正する可能性があることをここに記載しておく。
Reactアプリでのi18n対応(国際化/多言語対応)にi18nextを使ってみる
これはi18n対応のために i18next
と react-i18next
を使ってみた備忘録となる。
目次
- 目次
- Reactアプリでのi18n対応(国際化/多言語対応)にi18nextを使ってみる
- react-intlとi18next
- サンプルアプリの雛形生成
- react-i18nextのセットアップ
- namespacesについて
- 言語を切り替える機能を実装する
- 翻訳した言語の管理方法
- Transを用いて、HTMLタグが使われている箇所を多言語化する
- addResourceBundleとremoveResourceBundleを用いて、必要て最低限のresourceのみを利用する方法
- react-i18nextでObject(...) is not a functionというエラーに悩まされた
Reactアプリでのi18n対応(国際化/多言語対応)にi18nextを使ってみる
仕事で多言語対応をすることになり、i18next
を使うことにした。
Introduction - i18next documentation
Introduction - react-i18next documentation
react-intlとi18next
ちなみに react i18n 対応
で検索すると、なんと驚いたことに過去にQiitaに書いた自分の記事が一番目にヒットした(2019年9月時点)。
2019年9月時点で 16イイね
がついているし、私にしては大健闘な状況である。
QiitaのSEO効果の偉大さを改めて思い知った。
こちらの記事では react-intl
を使用しており、一応の使い方は理解したつもりだが、なぜ今回 i18next
を使うことにしたかというと、うちの会社の別のサービスで既に導入実績があるからだ。
私が勤めている会社は、基本的に私以外は皆 凄腕エンジニアばかりで(もちろん、これはお世辞ではない)、 多言語対応周りの実装のレビューをしたりしながら、ふむふむこうやって使うのか、なるほどなーといつも勉強させてもらっていた。
そうこうしているうちに自分がメインで担当しているサービスでも一部多言語対応をしていくことになったため、既に皆が触っている i18next
のほうがメンテナンスもしやすいし、社内に知見もたまってきているというわけで、こちらを導入することにしたというわけである。
というわけで、これは i18next を使ってみた、的な備忘録となる。
実際の仕事で使うやり方とは多少異なってくると思うが、自分の理解を深めるために、一通り触ってみたメモをこちらに残しておく。
サンプルアプリの雛形生成
create-react-app
を使ってサンプルアプリの雛形を作成していく
npx create-react-app react-i18next-sample cd react-i18next-sample yarn start
create-react-appでブラウザが勝手に立ち上がらないようにする
ちなみに私はcreate-react-app
でyarn start
したときに勝手にブラウザが立ち上がる挙動が許せない質なので、下記のようにpackage.json
を書き換えている。
diff --git a/package.json b/package.json index 52a2f12..0730227 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "react-scripts": "3.1.2" }, "scripts": { - "start": "react-scripts start", + "start": "BROWSER=none react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject"
これらの設定は下記に記述がある。
Advanced Configuration | Create React App
react-i18nextのセットアップ
ここからreact
でi18next
を使っていくための設定を行っていく。
これらの記述はだいたい下記のドキュメントを読んでいけば、わかるようになっている。
Getting started - i18next documentation
Getting started - react-i18next documentation
実際の実装については下記が参考になる
react-i18next/example/react at master · i18next/react-i18next · GitHub
一つだけ注意点。
自分がここから書いていく記述では、 SSR
は考慮しないものとしていることを先に書いておく
yarn add i18next react-i18next
i18n.js
というファイルを作成する
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; const resources = { en: { translation: { 'Learn React': 'Learn React' } }, ja: { translation: { 'Learn React': 'Reactを学ぶ' } } }; i18n.use(initReactI18next).init({ resources, fallbackLng: 'en', debug: true, interpolation: { escapeValue: false } }); export default i18n;
HOCで使う場合はwithTranslationを使う
HOCを使う場合は withTranslation
を用い、下記のようにしてi18next
の機能を使う
src/App.js
を下記のように書き換える
import React from 'react'; import logo from './logo.svg'; import './App.css'; import './i18n'; import { withTranslation } from 'react-i18next'; function App({ t }) { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > {t('Learn React')} </a> </header> </div> ); } export default withTranslation()(App);
i18n.js
内のfallbackLng: 'en'
をfallbackLng: 'ja'
に書き換えることで言語が変わるのが確認できる。
hookで使う場合はuseTranslationを使う
hookで使う場合は useTranslation
を使う。
上のサンプルと見比べてみると、使い方の違いがより分かるかと思う。
import React from 'react'; import logo from './logo.svg'; import './App.css'; import './i18n'; import { useTranslation } from 'react-i18next'; function App() { const { t, i18n } = useTranslation(); // 下記のような書き方でもOK // const [ t, i18n ] = useTranslation(); return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > {t('Learn React')} </a> </header> </div> ); } export default App;
namespacesについて
ちなみにここまでしれっと translation
という namespaces
を使ってきたが、ここについては下記のドキュメントが参考になるかと思う。
Namespaces - i18next documentation
i18nextのnamespaceについてだが、小規模なプロジェクトであればすべてのテキストを一つのファイルに纏めて利用する形で事足りると思うが、大規模なサービスを運用したい場合はそうも言ってられなくなる。
そこでnamespaceを区切って、必要なテキストだけを読み込んでいこうということになる。
当然全てのテキストファイルが一度に読まれなくなるので読み込み時間の短縮などにもつながる。
ただ、namespaceを分けることによって、テキストの管理コストは上がるため、そこも考えてプロジェクト内で慎重に検討していったほうが良さそうというのが個人的な考え。
ドメインごとのテキストと共通で利用するテキストなど、どういう考え方で分けていくか?などを考えていく必要がある。
ちなみに i18next
の公式サイトでは、下記のような分け方で分けているという書かれている。参考にしてみるのも良いかも。
common.json -> あらゆる場所で再利用されるもの、例えばボタンのラベル「save」や「cancel」など。
validation.json -> すべての検証テキスト
glossary.json -> テキストの中で一貫して使われて欲しい単語
https://www.i18next.com/principles/namespaces#semantic-reasons
translation というnamespaceの挙動について
translation
はdefaultで利用されるnamespaceとなる。
namespaceが必要がない場合は translation
というnamespaceがルートに位置する形となる。
例えば、このtranslation
というnamespaceがない場合、i18next自体が機能しなくなる。
例として、下記のような構成の場合、動かない。 (日本語の言語ファイルは割愛)
{ "Learn React": "Learn React", "Save to Reload text": "Edit <1>{{filename}}</1> and save to reload." }
import en from './en/translation'; import ja from './ja/translation'; export default { en, ja };
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import resources from './locales/resources'; i18n.use(initReactI18next).init({ resources, fallbackLng: 'en', debug: true, interpolation: { escapeValue: false } }); export default i18n;
この状態では動かない。
下記のように translation
をルートに持ってくることで動くことが確認できる。
{ "translation": { "Learn React": "Learn React", "Save to Reload text": "Edit <1>{{filename}}</1> and save to reload." } }
実際に動かすときは下記のように呼び出すことになる。
// 呼び出すとき t('Learn React')
この挙動からも translation
がルートには必要であることが分かる。
次はこの translation
を別の namespace1
というnamespaceに変えてみる。
すると呼び出し方が変わる。
{ "namespace1": { "Learn React": "Learn React", "Save to Reload text": "Edit <1>{{filename}}</1> and save to reload." } }
呼び出すときはこのnamespace1を込みで呼び出す必要がある。
(勿論この例はあくまでresourceファイルをそのままi18next側に読み込ませているからなわけで、読み込ませ方によって異なる呼び出し方になると思う)
// 呼び出すとき頭にnamespaceを指定する t('namespace1:Learn React')
さらには上の状態にルートに translation
を持ってくる
{ "translation": { "namespace1": { "Learn React": "Learn React", "Save to Reload text": "Edit <1>{{filename}}</1> and save to reload." } } }
この場合呼び出し方が下記のように変わってくる。
t('namespace1.Learn React')
以上のような挙動だが、たぶんここらへんで実装しているような気がするので、個人的なメモとして残しておく。
https://github.com/i18next/i18next/blob/master/src/ResourceStore.js#L36-L50
またこのような挙動については、ドキュメントの下記のページにも記載があるので、そちらを熟読したほうが本質的な理解に繋がりそう。
https://www.i18next.com/translation-function/essentials#accessing-keys-in-different-namespaces
Namespaces - i18next documentation
translationを言語のテキストファイルに含めたくない場合
このあとのサンプルにも登場させる書き方でいけば、言語テキストを格納するjsonファイルに translation
を含める必要はなくなる。
(こちらについては 翻訳した言語の管理方法
という項目に書いている)
かんたんなサンプルを下記に記載する。
{ "namespace1": { "Learn React": "Learn React", "Save to Reload text": "Edit <1>{{filename}}</1> and save to reload." } }
下記のように言語ファイルは一つに予めまとめておくようにして、その後まとめたこれらのresourceをi18nextの初期化処理時に食わせる流れとする。
import enTranslation from './en/translation'; import jaTranslation from './ja/translation'; export default { en: { translation: enTranslation }, ja: { translation: jaTranslation } };
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import resources from './locales/resources'; i18n.use(initReactI18next).init({ resources, fallbackLng: 'en', debug: true, interpolation: { escapeValue: false } }); export default i18n;
という形でセットすることで、下記のように呼び出すことが可能となる。
t('namespace1.Learn React')
言語を切り替える機能を実装する
i18n.changeLanguage
という関数が用意されているので、こちらで切り替えを実装できる。
(雑なサンプルで恐縮である)
import React from 'react'; import logo from './logo.svg'; import './App.css'; import './i18n'; import { withTranslation, Trans } from 'react-i18next'; function changeLanguage(i18n, lang) { i18n.changeLanguage(lang); } function App({ t, i18n }) { const filename = 'src/App.js'; return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> <Trans i18nKey="Save to Reload text"> Edit <code>{{ filename }}</code> and save to reload. </Trans> </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > {t('Learn React')} </a> <div> <p>Change Language</p> <button onClick={() => changeLanguage(i18n, 'en')}>en</button> <button onClick={() => changeLanguage(i18n, 'ja')}>ja</button> </div> </header> </div> ); } export default withTranslation()(App);
翻訳した言語の管理方法
ここでは locales
というディレクトリを作り、その配下に各種言語ごとに翻訳したリソースを格納、
これらはresources.js
というものでまとめて export
することで、アプリ側に読み込んでいくような設定とする。
このやり方の場合、言語の変更を行う場合はソースコード自体を変更するしかないので、実際の運用ではもう少し考える必要がありそうだ。
本来であれば、翻訳した言語は別のSaaS
的なもので管理していき、ソースコードを変更せずとも言語ごとのテキストを変えられるようにしたほうが良いと思われる。
例えばi18next
では locize
という多言語管理用のSaaS
が親和性が高いようだ。が、結構エンジニアフレンドリーなサービスのようにも感じるので、多言語リソース管理をエンジニアではない人間が担当する場合は、管理を少しばかり考える必要がある。
localization & translation management platform | locize
例えば、先日ブログにも書いたが、contentful
などのHeadless CMS
などで管理していくのも一つだと思う。
Headless CMS の Contentful からデータを取得して、Next.jsのページで表示させるメモ - at backyard
少し話がそれてしまったが、多言語リソースの管理について書いていく。
先程も書いたが、locales
というディレクトリを作成し、下記のように言語を管理していく
src/locales ├── en │ └── translation.json ├── ja │ └── translation.json └── resources.js
ここのtranslation.json
というファイルには、下記のようにそれぞれの言語でのテキストが入ることになる。
en/translation.json
{ "Learn React": "Learn React" }
ja/translation.json
{ "Learn React": "Reactを学ぶ" }
これらの言語ファイルをresources.js
でまとめてexport
する形だ
import enTranslation from './en/translation'; import jaTranslation from './ja/translation'; export default { en: { translation: enTranslation }, ja: { translation: jaTranslation } };
そして、i18n.js
では下記のようにresouces.js
を読み込む形に修正する
diff --git a/src/i18n.js b/src/i18n.js index 5673005..bed5f11 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -1,18 +1,6 @@ import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; - -const resources = { - en: { - translation: { - 'Learn React': 'Learn React' - } - }, - ja: { - translation: { - 'Learn React': 'Reactを学ぶ' - } - } -}; +import resources from './locales/resources'; i18n.use(initReactI18next).init({ resources,
これでひとまずのところ、言語ファイルを分離して管理することができるようになった。
ここについては正直もう少し考えてみる必要がありそうだが、とりあえずの ことはじめ
として一旦このような形にした。
Transを用いて、HTMLタグが使われている箇所を多言語化する
下記のようにTrans
componentを用いて多言語化できる。
diff --git a/src/App.js b/src/App.js index 67b04a9..bbaa97d 100644 --- a/src/App.js +++ b/src/App.js @@ -2,19 +2,23 @@ import React from 'react'; import logo from './logo.svg'; import './App.css'; import './i18n'; -import { withTranslation } from 'react-i18next'; +import { withTranslation, Trans } from 'react-i18next'; function changeLanguage(i18n, lang) { i18n.changeLanguage(lang); } function App({ t, i18n }) { + const filename = 'src/App.js'; + return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> - Edit <code>src/App.js</code> and save to reload. + <Trans i18nKey="Save to Reload text"> + Edit <code>{{ filename }}</code> and save to reload. + </Trans> </p> <a className="App-link"
このように記述した場合、テキストファイルには下記のように記述する。
日本語テキスト
{ "Learn React": "Reactを学ぶ", "Save to Reload text": "<1>{{filename}}</1>を編集して保存すると、リロードされます。" }
英語テキスト
{ "Learn React": "Reactを学ぶ", "Save to Reload text": "<1>{{filename}}</1>を編集して保存すると、リロードされます。" }
<1>
で囲むというところが若干分かりにくい気もするが、、、こういうものなのだろうか?
自分自身あまり使い込めていないので、とりあえず使っていってみる!
この Trans
コンポーネントに関する詳細については、下記のページに詳しく書かれている。
Trans Component - react-i18next documentation
addResourceBundleとremoveResourceBundleを用いて、必要て最低限のresourceのみを利用する方法
例えば一度に複数の言語ファイルを読み込みたくないという要望はあると思う。
そういうとき、必要な言語ファイルだけを読み込むにはどうすればよいか?
そこで登場するのが addResourceBundle
という関数になる。
また、逆にresourceを削除するための removeResourceBundle
という関数もある
https://www.i18next.com/how-to/add-or-load-translations#add-after-init
そこでこれらのコードを利用して、下記のようなコードを作成してみた
まずi18n.jsである。
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; i18n.use(initReactI18next).init({ resources: {}, fallbackLng: 'en', debug: true, interpolation: { escapeValue: false } }); export default i18n;
ここでは空のresourcesを渡しているが、最初からなんらかの言語情報をresourcesとして渡しても問題ない
ひとまずここでは空のresourcesを渡して、後で動的にリソースを格納していくことにする。
さらに言語resourceの追加・削除、並びに利用する言語の変更を行うための関数を i18-utils.js
という名前で作成した。
import resources from './locales/resources'; const resourceKeys = Object.keys(resources); export const changeLang = (i18n, lang) => { // 更新対象のresourceを追加する i18n.addResourceBundle(lang, 'translation', resources[lang].translation); // 言語変更処理 i18n.changeLanguage(lang); // 不要になったresourceは削除する const removeLnaguages = resourceKeys.filter((languag) => languag !== lang); for (const removeLang of removeLnaguages) { i18n.removeResourceBundle(removeLang, 'translation') } return; }
そしてこれらのコードを使った形で下記のようなコードを書く。
ここでは useTranslation
を用いたコードで書いていく。
import React, { useCallback, useEffect } from 'react'; import logo from './logo.svg'; import './App.css'; import './i18n'; import { useTranslation, Trans } from 'react-i18next'; import { changeLang } from './i18n-utils'; const App = () => { const [ t, i18n ] = useTranslation(); const filename = 'src/App.js'; const onClickChangeLanguage = useCallback((lang) => { changeLang(i18n, lang) }, [i18n]); useEffect(() => { changeLang(i18n, 'en') }, []) console.log(i18n.logger.options.resources) return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> <Trans i18nKey="Save to Reload text"> Edit <code>{{ filename }}</code> and save to reload. </Trans> </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > {t('Learn')} </a> <div> <p>Change Language</p> <button onClick={() => onClickChangeLanguage('en')}>en</button> <button onClick={() => onClickChangeLanguage('ja')}>ja</button> </div> {i18n.languages.map(lang => ( <p key={lang}>{lang}</p> ))} </header> </div> ); } export default App;
これを実行すると、正常に言語切替が行われる。
また言語切替が行われるタイミングでi18n内に格納されている言語のうち、選択されたもの以外のresourceが削除される。
これは console.log(i18n.logger.options.resources)
というデバッグ用の関数を差し込むことで確認が可能。
i18n.languagesの中身について
上のコードでデバッグ目的な下記のような記述を書いた
{i18n.languages.map(lang => ( <p key={lang}>{lang}</p> ))}
例えば英語を選択した場合、 en
が入るが、日本語を選択した場合、ここには en
, ja
という2つが入る。
なぜ en
はこの配列の中に居座り続けているのだろうかと考えたが、ここは
i18n.use(initReactI18next).init({ resources: {}, fallbackLng: 'en', debug: true, interpolation: { escapeValue: false } });
ここで fallbackLng
として指定していたからだった。
ここで指定すると、i18n.languages
の中には居座り続ける仕様となっている、というのは実装する上で頭の中に入れておいたほうが良いかもしれないと思った次第。
react-i18nextでObject(...) is not a functionというエラーに悩まされた
react-i18next
を触る上で、少しハマったことがあったので、最後に書き記しておく。
ここまで書いていたようなことを、とある環境で試していたところ、なぜだか Object(...) is not a function
というエラーが出る。
最初、自身のReactの使い方が間違っているのかと疑っていたが、なんてことはなく、react
, react-dom
のバージョンが古いだけだった。。
私はこの原因を突き止めるのに3時間ほどかけてしまった。猛省した。
B/W、イバラキングのごじゃっぺラジオZに出演してきました!
先日書いていたとおり、B/Wにて、イバラキングのごじゃっぺラジオZに出演してきました!
ラジオの公開収録ということで最初は緊張していたものの、始まれば意外と落ち着きながら(?)楽しんで話すことができ、最高に楽しい時間を過ごすことができました。ありがとうございました!
以下、B/Wのツイートを引用
本日つくばセンターのスタジオ・センにて行われた、ラヂオつくば「イバラキングのごじゃっぺラジオZ」の公開収録、最高に楽しかったです!ありがとうございました!公開収録中、喋っていた諸々の情報に関するURLを呟いていきますので、チェックいただけたら幸いです!#gojaradi
— B/W (@bwisbornto2004) September 26, 2019
本日の収録中に流していただいたMellow Yellowの音源については下記のURL内から無料ダウンロードできます!是非チェックしてみてください。#gojaradihttps://t.co/iXy4TPen0q
— B/W (@bwisbornto2004) September 26, 2019
また、B/Wの公式サイトについては下記URLからアクセスできます。タイミングを見つけて随時更新していく予定なので、ブックマークしていただけると幸いです。#gojaradihttps://t.co/g55eo6qhCG
— B/W (@bwisbornto2004) September 26, 2019
番組内で話していたTiktokについては下記のURLからアクセスできます!#gojaradihttps://t.co/p3s1TzBmsx
— B/W (@bwisbornto2004) September 26, 2019
また、このアカウントとは別に番組内で呟かせてもらった、別のTwitterアカウントについては @shinshin86 となります。ご質問等ありましたら、こちらにメッセージいただけると早めに返信できそうです!#gojaradi
— B/W (@bwisbornto2004) September 26, 2019
本日公開収録された番組の放送は28日(土)22時からとなります。是非当日の放送を聞かれる方は、これらのツイートも併せてチェックいただけると幸いです!それでは! #gojaradi
— B/W (@bwisbornto2004) September 26, 2019
スーパーカーやHomecomings好きなら必聴かも、な台湾のインディギターポップバンド、DSPS
たまたま見つけた下記の記事。
この記事タイトルだけで読みたくなるわ!というわけで後で読むためにメモ。-> スーパーカーに憧れた台湾バンドDSPSが抱く「自由」への切実さ https://t.co/ZflLcsu3Qn
— Yuki Shindo (@shinshin86) September 23, 2019
読んで DSPS
聴いてみたら、やはり良かった。
今日のお仕事Musicはこのバンドのアルバムになりそうだ。
関係ないけど、最近起床時間が早くなってきた。
今年は7時頃に起きるのが習慣だったけど、6時起きに移行してきた。朝早く起きるのはやはり気分が良いもので、グラスにたっぷりと注いだアイスコーヒーを飲みながら、朝焼けの空を眺めていると、なにか曲でも作りたくなってくる。
さて、曲は作らずに仕事の準備だ。PCをリュックに詰め込んで、都内へ向かう。
ブログのタグと、自分をコントローすることの難しさについて
たまには日記っぽいこと書くかと、はてなブログのアプリを開いて、何も考えずに書き出した。
日記っぽいこと書くならタグも '日記' だろうということで日記というタグをつけてみたが、ふと他に日記というタグをつけたポストを書いたかな?と思い、自分のブログを読み返そうとしたが、なんだかそれだけで1時間ぐらい経ってしまいそうな気がしたので、辞めた。
たぶん私だけじゃないだろうが、"あ、そういえばあのバンドの新作聴いてみようかな"と仕事中にApple musicで検索をかけて流すだけのはずが、気づいたら過去のリミックス集とかを色々調べ始めてしまい30分くらい経ってしまう、とかは割とあることだ。
この前だってトムヨークの新作を聴くだけのはずが、過去作やリミックスから、リミキサー陣それぞれのアルバムを検索するに至って、変な疲れを感じたりした。
ちょっとのつもりが思いがけず時間をかけてしまうのはあるあるなので、最近私は自制している。
自制といえば、ここ最近意識的にノンアルコールの日を作るようになった。
別に健康に気を使っているわけではなく、毎日お酒を飲むのが習慣化しているので、その習慣を自ら破ってみようと思い立ったのだ。
ただそんなことを思っていても友人から誘われるとお酒はついつい飲んでしまう。そんな酒の席で、"最近意識的にノンアルコールの日を作ろうとしていてさ〜本当は今日もノンアルコールにするつもりだったのに、飲んじゃった"、なんて話すものだから、私の話は説得力皆無の状態で酒場の隅に追いやられてしまうのだった。
お酒といえば、先日、常陸野ネストビールでお馴染みの木内酒造に足を運んだ。これは近いうちに改めて書こうと思うので、またその時に。 とても楽しかったので、茨城の水戸の方に行く方で、クラフトビール好きの方は是非いってみると良いと思う。友人同士でもカップル同士でも夫婦ででも楽しめるはずだ。グッズも可愛くて、私もグラスとかステッカーとか諸々買ってしまった。おススメ。