日々の記録。

プログラミングのメモや感じた事などを記録。

C++講座 その6 列挙型

列挙型を利用すると、定数の集合に名前を付ける事ができ、新しい型のように扱う事ができる。

enum Sex {
MALE,
WOMAN
};

enum ButtonType {
NORMAL,
IMAGE,
TOGGLE
};

定数は明示しなければ0から連番で0,1,2,...と付けられる。 = 1のように値を明示することもできる。

enum ResultType {
NO_ERROR = 0,
IO_ERROR = -1,
MEMORY_ERROR = -2
};

サイズ

enum内の定数値にint, unsigned intとして表現できない値が含まれていない限り、sizeof(int)よりは大きくならない。

サイズは環境による(コンパイラオプション等で変更できるかもしれない)。

小休止

cut & loopと言うiOS向けの語学用オーディオプレイヤーを作成しています。 TOEICなどの語学教材のMP3やCD音源をご利用の際にぜひ試してみてください。

‎「cut & loop 語学用オーディオプレイヤー」をApp Storeで

メリット

enumを利用する事の最大のメリットは、関数などの引数で渡す値や戻り値を明示できる点にある。

例えば

#define NO_ERROR (0)
#define IO_ERROR (-1)

int foo() {
  return NO_ERROR;
}

void bar() {
  int result = foo();
}

と書くよりも

enum Result {
IO_ERROR = -1
NO_ERROR,
};

Result foo() {
  return NO_ERROR;
}

void bar() {
  Result result = foo();
}

と書いた方が、関数の戻り値が明確になり可読性が高まる。コンパイラも型をチェックしてくれるので、誤った定数値を渡すリスクも減らせる。

デメリット

ないと思う。 以前、enum禁止のコーディングルールを見たことがあるけど信じられない。

注意点

C言語ではtypedefを付ける

C++ではtypedef不要だけど、Cでは必要(C99未確認です)。 定義ファイルをCでも共有する場合は、typedefを付ける必要がある。

通信プロトコルでの利用時

TCP/IPを利用する場合、recv/sendで構造体を直接読み書きする場合には、環境によりサイズが異なる可能性があるため、enumを利用しないこと(ちゃんと構造体毎にシリアライズする関数を定義してあるなら別かもしれませんが・・・。)。

enumの定数名はグローバルに属するため重複しやすい

namespace、classに属さないenumの定数名は、グローバルに属するため一意にする必要がある。 C++で定義する場合、classまたはnamespace内で定義すること。

enum A {
  AAA,
  BBB,
  CCC
};

enum B {
   CCC,
   DDD,
   EEE
};

void foo() {
  AAA // OK
  CCC // コンパイラはA::CかB::Cか区別できない.
}

namespace aaa {
  enum A {
    AAA,
    BBB,
    CCC
  };
}

namespace bbb {
  enum B {
     CCC,
     DDD,
     EEE
  };
}

void foo() {
  aaa::AAA // OK
  aaa::CCC // OK.
}

おまけ

定数の数を定義

enum DEVICE_TYPE {
  IPHONE_TYPE,
  IPAD_TYPE,
};

#define NUM_DEVICE_TYPE (2)

としても良いけど、定数値が0から連番で始まるなら

enum DEVICE_TYPE {
  IPHONE_TYPE,
  IPAD_TYPE,
  NUM_DEVICE_TYPE
};

これでも良い、と思う。

「記憶力を強くする」にみる英語教材「Duo」の勉強方法

はじめに...

語学教材のCDでは複数の文章を1トラックで記録していますが、文章毎に再生可能なアプリなどを利用すると、より学習しやすくなります。

例えば、私が作成したiOS用アプリcut & loopを利用すると、 1トラックに記録されている文章を、簡単に文単位に切り取る事ができ、文ごとの繰り返し再生や、速度を変えた再生などを行う事ができます。

興味のある方は、iTunes Store cut & loopを参照下さい。

「記憶力を強くする」について

 最近「記憶力を強くする」という本を読み、その中で解説されていた記憶方法をもとに、勝手にDuoの勉強方法を考えてみました。(私は専門家ではないので効果については未知数ですが、自分自身試して、Duoの推奨勉強である「BGMのように聞く」よりは効果があると実感しています。)

 ちなみに「記憶力を強くする」は、脳科学の視点から、記憶の仕組みについて分かりやすく解説されていて、ちょっとでも記憶力に興味がある方にはおすすめです。この記事では、特に第6章の「科学的に記憶力を鍛えよう」を参考にしています。

方法1 演じる

動機:感情(情動)が伴うと、LTPという記憶力を向上させる現象が生じやすい。

方法:Duoの文章も「ただ読むのでは無く、その人になったつもりで感情を込めて読む」

方法2 関連づける

動機:シナプス可塑性の「連合性」という性質。単一の事でもできるだけ多くの事を関連づけた方が、覚えやすくなる。さらに自分の経験などに紐づけると、エピソード記憶になり記憶しやすくなるし、思い出しやすくなる。

方法:Duoの文章は、前後につながりがある文章が多いので、1文ずつというより文脈で覚える。 (他に、文章を自分の身の回りに置き換えて作り替えりしてみる。)

方法3 好奇心を持つ

動機:興味や好奇心を持つと、記憶に関係するθ波という脳波が発生し、記憶しやすくなる。

方法:Duoの文章を漠然と読むのではなく、文章の行間にある事も想像し、さらにその人になったつもりで読む。

余談:歳を取ると物忘れがひどくなりますが、物事に対する情熱が薄れたり、感動が薄くなった結果、記憶力が落ちたように感じてしまうようです。

方法4 聞く

動機: 進化の過程では、動物は目よりも耳を良く利用していた。今でも耳の記憶力の方が強い。

方法: 復習用CDなどで音を聞き、音から文章を覚える。その上でテキストを読む。

方法5 理解する

動機:理解していない事は、覚えられない。 (法則性を導き出したり、自分の記憶に関連づける事で、物事が理解できその物事を知識として利用できるそうです。)

方法:CDを聞いて意味が分からない場合は、無理に聞き取ろうとせず、まずはテキストを見て文章上の単語や意味を確認する。

方法6 まずはおおまかに理解する

動機:いきなり細かく覚えようとするよりも、まずはおおまかにとらえた方が覚えやすい。

方法:最初からDuoにある全ての単語を覚えようとはせず、まずは文章を暗唱できるようにし、徐々に単語も覚える。

方法7 アウトプットする

動機:覚えた事を誰かに説明したり、誰かと演じあったりする事で、その記憶は「エピソード記憶」となり、思い出しやすくなる。

方法:聞いたままを声にだして読んでみたり、友人同士で読み合ったりする。

方法8 エビングハウスの忘却曲線

動機:脳は覚えた直後にどっとわすれて、残った記憶は多少長く残る。完全に忘れるまでに復習をすると、1度目に忘れてしまった事も覚えやすくなる。

方法:復習を1日後、2日後、1週間後、2週間後、1ヶ月後と間隔を徐々に空けながら行う。 ※エピソード記憶は次第に意味記憶になるので、定期的にアウトプットする事が大切なようです。

方法9 一度に詰め込みすぎない

動機:人は「忘れる」という事を意識的にできないが、内容が類似した事を覚えようとすると記憶は上書きされる。(この現象を「記憶の干渉」というそうです)

方法:一度の勉強で詰め込むのではなく、1section、またはその半分など、自分に無理のない量を覚える。

まとめ

上記の方法を組み合わせた一例として、私は次のようにsectionを学習しています。

  1. 前回覚えた文章を暗唱する。
  2. 暗唱できなかった文章を確認し、暗唱できるようにする。
  3. 新しい1文を聞く
  4. 意味が分からなければ、テキストを見てその文章を覚える。(英文と日本語の意味も)
  5. その1文を聞き、聞いたままに発声してみる。(できるだけその人になりきって)
  6. テキストや音声を参照せずに、発声できるまで4,5を繰り返す。
  7. 暗唱できるようになったら、次の文章も2-5と同様の手順で、暗唱できるようにする。
  8. 覚えた文章を1度全て暗唱してから( この例では2で覚えた1文と、6で覚えた一文)、2に戻る。 この手順を半sectionから1sectionをめどに行います。あとは復習として、過去に覚えた内容を暗唱します。

この方法で、実際に英語が喋れるようになるかは未知数ですが、Duoの例文を覚えるという点においては、今のところ効果を実感しています。

VirtualBoxにCentOS, mysql, ruby, railsをインストールする

案の定いくつかはまったところがあったのでメモに残します。

環境

前提

必要に応じて、各コマンドはsudoで実行してください。

  • CentOSのイメージファイルのインストール

CentOSのダウンロードページからisoファイルをダウンロードします。

VirutalBoxのインストール

こちらなどを参考にインストール

注意点

ネットワークの設定

こちらを参考に設定します

centosのアップデート

必要なものを入れます。これをいれないと,後々rubyrailsのインストールにはまります。

yum update
yum groupinstall 'Development tools'
yum install openssl-devel
yum install sqlite-devel
yum install mysql-devel

mysqlのインストール

このサイトを参考にインストール&セットアップ

rubyのインストール

このサイトに従ってrbenvとrubyをインストールします

rbenvを入れることにより、rubyのバージョン管理を行いやすくできます。

bundler railsのインストール

bundlerを入れることにより、railsとそれに関連するgemをプロジェクト単位で管理 できるようになります。

参考サイト

railsとプロジェクトを一式を保存するディレクトリ上にGemfileを作成し、 下記のようにします。

source "http://rubygems.org"
gem "rails", "4.0.0" # ←ローカルインストールしたいRailsのバージョンを指定。指定しなければ最新版が入る。

railsプロジェクトの新規作成

Gemfileのあるディレクトリ上で下記コマンドを実行し、railsをインストールします。

> bundle install --path vendor/bundle
> # exampleのrailsプロジェクトを作成する。
> #--skip-bundleを忘れずに!! これを忘れるとruby直下にgemがはいってしまう。 
> bundle exec rails new example --skip-bundle

railsの仕方

# gemのインストール先をvendor/bundleにする
> bundle install --path vendor/bundle

rails,rakeの起動方法

# 必ずbundle execを介すこと
> bundle exec rails
> bundle exec rake

rails4 jQuery.readyが働かない場合の対処法

rails4から導入されているturbolinksという機能が影響しているらしい。

参考

とりあえずの対処

// $(document).ready(function() {}) ↓に置き換える。
$(document).on('page:change', function() {});

rails4 fields_forの要素に対してはfile_fieldが働かない?

Rails4でfields_forの要素に対して、file_fieldを行ってもファイルアップロードが行えなかった。 form_forの要素に対して、行う必要がある。

NGな例

<%= form_for(@model) %> |f|
  <%= f.fields_for(@model.file) %> |ff|
     <%= ff.file_field :fileinfo %>
  <% end %>
<% end %>

上のケースでは、request parameterにファイル情報が入ってこない。


OKな例

<%= form_for(@model) %> |f|
  <%= f.fields_for(@model.file) %> |ff|
     <%= f.file_field :fileinfo %>
  <% end %>
<% end %>

上のケースでは、request parameterにファイル情報が入ってくる。


FileMaker ProとRubyを接続してみた。

最近FileMaker Pro(以下FM)というDBを利用する機会があったのですが、このFMのスクリプトがどうしても好きになれず、rubyスクリプトが書けないか模索してみました。

(好きになれない理由: FMではスクリプトを作成するために、本来のテーブル構造には不要なテーブルオカレンスやらフィールドを追加しなければならず、構造が汚れるのが嫌。簡潔から遠のく感じがします。)

結論

先に結論を書くと、ODBCによる接続はあきらめました。

色々なサイトを参考(※1)にして、FileMaker〜iODBC間の接続は行えたのですが、ruby-odbc〜iODBC間でSQLを発行すると、select文でsegmentation faultが発生することがあり、これがどうしても解決できずあきらめました。(どうやらruby-odbcruby1.9.1 (32bit)までしか対応していない?)

※1 参考にしたサイト

で、接続できた環境は以下の通りです。 rubyJDBCって接続できる環境ない?って思ったのが解決のきっかけでした。

・・・rubyはあきらめて、Javaruby実装であるjRubyで接続する事にしました。 今までjRubyの使い道ってどこにあるんだろうと思っていましたが、こんなところで使うことになるとは思いませんでした。

余談ですが、FileMaker Serverと接続する場合には、もっと良さそうなRfmというgemが存在するので、そちらを使った方が良いと思います。

手順

具体的な導入手順です。

1: jRubyをインストールする.

http://jruby.orgより、jRubyの最新版(バイナリ版)を任意のフォルダにダウンロードします。

以下は一例

# jRuby を /usr/local/jRuby-1.7.10  に保存したとします。
cd /usr/local
ln -s jRuby-1.7.10 jRuby_current_version # symbolic linkを設定します。

2: PATHを設定します。

vim ~/.bash_profile # ログインシェルがbashの例
PATH="$PATH":/usr/local/jruby_crrent_version/bin/ #適当な行に追加する.

3: JDKが入っていない場合は、JDKをインストールします。

ダウンロード先 Java SDK Downloads

4: jdbc-helperをインストールします。

参考 jdbc-helper

jRuby -S gem install jdbc-helper

5: FileMakerJDBCドライバをインストールします。

参考 FileMaker Pro ODBCとJDBCガイド

FileMakerインストーラより、fmjdbc.jarを任意のフォルダにコピーします。

コピー先の例 ~/Library/JDBC/fmjdbc.jar

6: classpathの追加

vim ~/.bash_profile # ログインシェルがbashの例
export CLASSPATH=$CLASSPATH:~/Library/JDBC/fmjdbc.jar

以上で、jRuby-JDBCのインストールは終了です。

テスト

FileMaker

1: FileMaker Proでテストをするファイルを開きます。仮に"test.fmp12"とします。

2: ファイル 共有設定で[ODBC/JDBCを有効にする]を選択します。

3: ODBC/JDBC共有をONにして、ファイルのアクセスを[すべてのユーザ]にします。 (必要に応じて制限します)

4: ファイルオプションの[開く]タブにてアカウント名とパスワードを指定します。 (無指定だとJDBCから接続できなかったので、念のため指定します)

注意:接続する際は、test.fmp12は開きっぱなしの必要があります。

ソース

1: test.rb

テストソースを、テスト環境に合わせて作成します。

require 'jdbc-helper'

con = JDBCHelper::FileMaker.connect('localhost', 'testuser', 'password', 'test')
sql = 'SELECT id, name, "点数" FROM "テスト"'
con.query(sql) do |row|
  id, name, score = row
  puts "#{id} #{name} #{score}"
end

con.close

2: 実行

jruby test.rb

以上です。