Django1.5 tutorial Part4 個人的メモ
簡単なフォームを書く
polls/detail.html
にフォームを以下のように追加する.
<h1>{{ poll.question }}</h1> {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} <form action="{% url 'polls:vote' poll.id %}" method="post"> {% csrf_token %} {% for choice in poll.choice_set.all %} <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" /> <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br /> {% endfor %} <input type="submit" value="Vote" /> </form>
コードの説明:
- 各投票(Poll)の選択肢(choice)のラジオボタンを表示
- フォームのアクションは
{% url 'polls:vote' poll.id %}
で指定 forloop.counter
はforタグがそのループを何回回ったかの回数- POSTの場合,CSRF(Cross Site RequestForgeries)に注意する必要があるので,
{% csrf_token %}
を使って対応する必要がある.
次にpolls/views.py
中のvote()
関数を実装する.
from django.shortcuts import get_object_or_404, render from django.http import HttpResponseRedirect, HttpResponse from django.core.urlresolvers import reverse from polls.models import Choice, Poll # ... def vote(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) try: selected_choice = p.choice_set.get(pk=request.POST['choice']) except (KeyError, Choice.DoesNotExist): # Redisplay the poll voting form. return render(request, 'polls/detail.html', { 'poll': p, 'error_message': "You didn't select a choice.", }) else: selected_choice.votes += 1 selected_choice.save() # Always return an HttpResponseRedirect after successfully dealing # with POST data. This prevents data from being posted twice if a # user hits the Back button. return HttpResponseRedirect(reverse('polls:results', args=(p.id,)))
ここでやっていることの説明.
request.POST
は辞書的なオブジェクトで,view側ではキーワード指定でsubmitされたデータを参照出来る.この例ではrequest.POST['choice']
でchoiceのvalue,すなわちchoiceのidを文字列で受け取っている.request.POST['choice']
はKeyErrorを発生させるかもしれないのでその例外処理を記述している- choiceのカウントをインクリメントした後はHttpResponseの代わりにHttpResponse.HttpResonseRedirectを返すようにしている.これはPOSTした後には結果ページにリダイレクトするべきというWeb開発のプラクティスに基づいている.
- reverse()関数を使っているのはview.pyでリダイレクト先のURLをハードコードするのを避けるためにである.上記例の
reverse('polls:results', args=(p.id,))
は以下の結果文字列を返す.
'/polls/3/results/' # この'3'はp.idの値である.
この辺りの詳しい説明はここを参照すること.
次にやることはresults()の修正
def results(request, poll_id): poll = get_object_or_404(Poll, pk=poll_id) return render(request, 'polls/results.html', {'poll': poll})
子の実装はdetail()とほとんど同じ.この冗長性を取り除く方法は後述.
そうしたら,polls/results.html
テンプレートを作成する.
<h1>{{ poll.question }}</h1> <ul> {% for choice in poll.choice_set.all %} <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li> {% endfor %} </ul> <a href="{% url 'polls:detail' poll.id %}">Vote again?</a>
総称viewを使う:少ないコードは良いことだ.
detail(), results(), そしてindex()はそれぞれ非常に似ている.これらは以下のような共通処理を行っている.
- URLを通じて得たパラメータに応じたデータをデータベースから取得
- テンプレートをロードしてレンダリングしたテンプレートを返す
これは非常に一般的なのでDjangoは"generic views"というショートカットを提供している.
Amend URLconf
polls/urls.py
を以下のように修正する.
from django.conf.urls import patterns, url from polls import views urlpatterns = patterns('', url(r'^$', views.IndexView.as_view(), name='index'), url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'), url(r'^(?P<pk>\d+)/results/$', views.ResultsView.as_view(), name='results'), url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'), )
Amend views
古いindex, detail, results関数を削除して総称viewを使う以下のコードに変更する.
from django.shortcuts import get_object_or_404, render from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from django.views import generic from polls.models import Choice, Poll class IndexView(generic.ListView): template_name = 'polls/index.html' context_object_name = 'latest_poll_list' def get_queryset(self): """Return the last five published polls.""" return Poll.objects.order_by('-pub_date')[:5] class DetailView(generic.DetailView): model = Poll template_name = 'polls/detail.html' class ResultsView(generic.DetailView): model = Poll template_name = 'polls/results.html' def vote(request, poll_id): ....
この例ではListView
とDetailView
という二つの総称viewを使っている.これらは
- 各総称viewは何のモデルに基づいているかを知る必要がある.これは
model
属性で指定する - DetailView総称viewはURLから"pk"という名前で主キーが捕捉されてくることを期待しているので,上記例では
poll_id
をpk
に変更している.
デフォルトで,DetailViewはテンプレートを”template_name
属性にその名前を設定してやればよい.
その他の総称viewの詳細はここを参照すること.
Django1.5 tutorial Part3 個人的メモ
Part 3ではwiewについて説明している.
哲学
view - はDjnagoアプリ中の一つのWebページに相当する.これは通常指定された(HTMLを表現する)テンプレートを持ち指定された機能を提供する.このチュートリアルのWeb-Pollアプリでは以下のviewを持つ
Poll "index" ページ - 最近のPollを表示する
- Poll "detail" ページ - ひとつのPoll questionを表示.結果ではなく投票用のフォーム表示する
- Poll "result" ページ - 特定のPollの結果を表示する
- Vote action - あるPollにおける特定の選択の投票を操作する
DjangoではWebページやその他のコンテンツはviewによってもたらさせる.DjangoはリクエストのURLを基に一つのviewを選択する.URLからviewを得るためにDjangoではURLConfs
という仕組みを使う.URLConfsはURLの(文字列)パターンとviewを紐付けるもので,urls.py
ファイルに紐付け情報を記述する.
最初のviewを書く
polls/views.py
に以下を記述する.
# polls/views.py from django.http import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the poll index.")
このviewを呼ぶためにはURLConfを使ってURLにこのindex()関数を紐付ける必要がある.polls/urls.py
を作成して内容を以下のようにする.
# polls/urls.py from django.conf.urls import patterns, url from polls import views urlpatterns = patterns('', url(r'^$', views.index, name='index') )
次の手順はルートのURLConf(settings.pyで指定する.デフォルトはプロジェクト名のディレクトリ配下に生成されたurls.py)内でpolls.urls
モジュールにリンクを追加することである.これはmysite/urls.py
中でinclude()
メソッドを追加することで実現する.
# mysite/urls.py from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', url(r'^polls/', include('polls.urls')), url(r'^admin/', include(admin.site.urls)), )
これでhttp://localhost:XXXX/polls/
で上記で作成したpolls.views.index()
の結果が得られる.
url()について
url()
関数は二つの必須引数(regex, view)と二つのオプション引数(kwargs, name)をとる.
url() 引数: regex
urlパターンを指定する正規表現.この正規表現にマッチすればviewに指定された関数を呼び出す.この正規表現ではURL文字列中のGETやPOSTメソッドのパラメータ,ドメイン名の部分はマッチング対象外である.
例) リクエスト: http://www.example.com/myapp/ の場合 URLConfでパターンマッチング対象となるのは:myapp/ リクエスト: http://www.example.com/myapp/?page=3 の場合 URLConfでパターンマッチング対象となるのは:myapp/
url() 引数: view
regexでマッチしたURLはこのview引数で指定した関数に処理を渡す.viewを呼び出す際に,HttpRequestオブジェクトを第一引数にし,正規表現で捕捉された項目をそれ以降の引数として渡す.regexで単純に捕捉した場合はその順番での引数として渡されるが,名前付きで捕捉した場合はキーワード引数として渡される.
url() 引数: kwargs
任意のキーワード引数をview関数に渡す.この引数は辞書型で渡す.
url() 引数: name
Django中でURLを一意に識別するために用いられる
さらにviewを書く
indexとは違う(今度は引数ありの)viewをいくつか追加する.
# polls/views.py def detail(request, poll_id): return HttpResponse("You're looking at poll %s." % poll_id) def results(request, poll_id): return HttpResponse("You're looking at the results of poll %s." % poll_id) def vote(request, poll_id): return HttpResponse("You're voting on poll %s." % poll_id)
これらの新規viewを以下のようにしてpolls.urls
モジュールに接続する.
# polls/urls.py from django.conf.urls import patterns, url from polls import views urlpatterns = patterns('', # ex: /polls/ url(r'^$', views.index, name='index'), # ex: /polls/5/ url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'), # ex: /polls/5/results/ url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'), # ex: /polls/5/vote/ url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'), )
include()
メソッドはマッチしたURLの文字列部分を取り除き,残りの文字列部分をインクルードされるURLConfに渡す.
実際に何か行うviewを書く
viewは以下のうちどちらを行う責務を持つ
- リクエスト内容を含んでいるHttpResponseオブジェクトを返す
- Http404等の例外を発生させる
以下の例はpolls/
にアクセスしたときに表示するindexページを最近5件のPoll questionをカンマ区切りで表示する.
# polls/views.py from django.http import HttpResponse from polls.models import Poll def index(request): latest_poll_list = Poll.objects.order_by('-pub_date')[:5] output = ', '.join([p.question for p in latest_opll_list]) return HttpResponse(output)
これはページデザインをハードコードしているので問題である.こういった問題に対処するためにDjangoではテンプレートシステムを提供している.
templateの作り方
- polls/templatesディレクトリを作る
- さらにその下にpollsディレクトリを作る
- そこにindex.htmlファイルを作る
- 以下のコードをindex.htmlに記述する
{% if latest_poll_list %} <ul> {% for poll in latest_poll_list %} <li><a href="/polls/{{ poll.id }}">{{ poll.question }}</a></li> {% endfor %} </ul> {% else %} {% endif %}
出来あがったindex.htmlは以下のパスとなる.
polls/templates/polls/index.html
何故templatesディレクトリの下に再度pollsディレクトリを作るかは,他のアプリのhtmlファイル等のリソースと名前が重複しないようにするため.
そしてpolls/views.pyのindex()を次のように変更する.
# polls/views.py from django.http import HttpResponse from django.template import Context, loader from polls.models import Poll def index(request): latest_poll_list = Poll.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = Context({ 'latest_poll_list': latest_poll_list, }) return HttpResponse(template.render(context))
このコードはtemplates/polls/index.htmlのテンプレートをロードし,コンテキストに通す.contextはテンプレート変数とPythonオブジェクトをマッピングさせるための辞書である.
ショートカット:render()
テンプレートをロードするコードは定石なのでショートカットが存在する.index()を書きなおしたものは以下の通り.
# polls/views.py from django.shortcuts import render from polls.models import Poll def index(request): latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] context = {'latest_poll_list': latest_poll_list} return render(request, 'polls/index.html', context)
render()メソッドは:
- 第一引数にrequestオブジェクト
- 第二引数にテンプレートの名前
- 第三引数に辞書型データ(テンプレート変数とPythonオブジェクトのマッピング)
を受け取り,HttpResponseオブジェクトを返す.第三引数はオプショナルらしい. 上記に変更すると,loaderとContextはインポートする必要は無くなる.
404エラーを発生させる
from django.http import Http404 # ... def detail(request, poll_id): try: poll = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404 return render(request, 'polls/detail.html', {'poll': poll})
もし要求されたIDのpollが存在しなければhttp404例外を投げる.上記コードでコンテキストに渡したpollオブジェクトはテンプレート中で以下のように書くと参照出来る.
{{ poll }}
ショートカット: get_object_or_404()
get()とHttp404のraiseは頻出イディオムなのでこれにもショートカットが存在する.以下はdetail viewを書きなおしたものである.
from django.shortcuts import render, get_object_or_404 def detail(request, poll_id): poll = get_object_or_404(Poll, pk=poll_id) return render(request, 'polls/detail.html', {'poll': poll})
get_object_or_404()は第一引数にDjangoのModelオブジェクトを受け取り,任意の数のキーワード引数をそれ以降で受け付ける.これらはmodelsのマネージャのget()メソッドに通すものである.もしオブジェクトが存在しなけばHttp404例外を投げる.
404(page not found)viewを書く
Http404例外があるviewで発生したら,Djangoは404エラーを操作するハンドラ―をロードしようとする.DjangoはルートURLConf中のhandler404変数を参照し,そこに登録されたハンドラ―(通常の場合と同様のview)を呼び出す.
500(server error)viewを書く
同様にルートURLConfにはhandler500
も定義できる.これはサーバーエラー(ステータスコードが500)に対応するviewを呼ぶ.
テンプレートシステムを使う
コンテキスト変数としてpollが与えられたとしたときのpolls/detail.htmlは以下のようになる.
<h1>{{ poll.question }}</h1> <ul> {% for choice in poll.choice_set.all %} <li>{{ choice.choice_text }}</li> {% endfor %} </ul>
Djangoのテンプレートシステムでは,変数の属性へのアクセスはdot-lookup構文
(ドットでオブジェクトを区切るおなじみのやつ)で行う.その手順は以下の通り({{ poll.question }}
を例として説明)
- オブジェクト
poll
上の辞書探索を行う. - もし見つからなければオブジェクトの属性探索を行う.(上記例ではこれで見つかる)
- もし見つからなければリストでの探索を行う.
より詳しいテンプレートの情報はここを参照.
テンプレート中のハードコードされたURLの削除
今のpolls/index.html
はURLがハードコードされている.
<li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
これだと沢山のテンプレートを使うプロジェクトではURLを変更するのが非常に難しくなる.でもurlsモジュール(urls.py)でurl()
関数に名前を付けていた場合,その名前でURLを参照することが出来る.
<li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>
こうすると,もしURLを変更したくなったらテンプレートを修正するのではなく,polls/urls.py
を変更すればよい.例えば以下のように
# added the wod 'specifics' url(r'^/specifics/(?P<poll_id>\d+)/$', views.detail, name='detail')
URL名の名前空間
{% url %}
の仕組みは便利だが,一つのプロジェクト中の異なるアプリ同士で同じURLを使っている場合,DjangoはどちらのアプリのURLかが判断出来なくなる.このような問題に対応するためにURLの名前空間を利用する.利用方法はプロジェクトのurls.py
のurl()
関数にnamespace
キーワード引数を指定すればよい.
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', url(r'^polls/', include('polls.urls', namespace="polls")), url(r'^admin/', include(admin.site.urls)), )
こうした後にテンプレートのURL指定を以下のようにすればOK.
<li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question }}</a></li>
Django1.5 tutorial Part 1 個人的メモ
DjangoのインストールはDjangoドキュメントの通りにやっておくこと.
Djangoがインストールされているかの検証は以下のようにコマンドラインで打ってバージョン情報が出力されればOK.
python -c "import django; print(django.get_version())"
プロジェクトの作成
django-admin.py startproject mysite
上記コマンドを実行するとmysiteディレクトリがカレントディレクトリに作成される.作成されるディレクトリ構成は以下の通り.
mysite/
manage.py # Djangoの管理コマンドを提供
mysite/ # このプロジェクトのためのPythonパッケージ
__init__.py
settings.py # このプロジェクトの設定情報を管理
urls.py
wsgi.py
開発用サーバー
開発用の簡易Webサーバーを立ち上げることでDjangoプロジェクトの動作チェックが可となる.外側のmysiteディレクトリに移動して以下のコマンドを実行する.
python manage.py runserver
# または python manage.py runserver 8080 # port番号の指定
# または python manage.py runserver 0.0.0.0:8000 # IPアドレスとport番号の指定
Databaseの設定
mysite/settings.py中のDATABASES辞書中の'default'項目の各設定値を適切なものに変更する.
- ENGINE
- 'django.db.backends.postgresql_psycopg2'
- 'dango.db.backends.mysql'
- 'django.db.backends.sqlite3'
- 'django.db.backends.oracle'
- その他
- 上記のどれかを指定する
- NAME
- SQLiteを使っている場合,databaseはマシン上のファイルとして存在するので,NAMEにはそのファイルのフルパスを指定すればよい.
- USER
- SQLiteでは必要ない
- PASSWORD
- SQLiteでは必要ない
- HOST
- Databaseが稼働しているホスト名を指定する
その他TIME_ZONEを設定したりする.
またINSTALLED_APPSタプルではこのDjangoインスタンスで有効化するアプリケーションを指定する.これらの各アプリケーションは少なくとも一つのDBテーブルを使用するので,以下のようにDBの初期化コマンドを実行する.このコマンドはDBの生成等を行う.
python manage.py syncdb
syncdbコマンドはINSTALLED_APPSの設定を見て必要なDBテーブルを生成する.
モデルの作成
次に行うのはappの生成である.DjangoはMTV(Model-View-Template)モデルのフレームワークらしい
DjangoにおけるProjectとappsの違い
appsはWebアプリケーション(ブログ等)で,Projectは特定のWebサイトにおける設定やappsのコレクションである.なので,あるProjectは複数のappsを持つ事が出来るし,あるappは異なる複数のProjectに所属することも出来る.
また,appsはpythonのパスが通っているところならどこに置いておいても動作は可能(実際はただのPythonパッケージなので)だが,通常は所属するProjectのディレクトリ配下に置かれる.
モデル作成
appを作るにはmanage.pyを実行する.
python manage.py startapp polls
このチュートリアルではpollsというアプリを作成している.上記を実行するとpollsディレクトリが作成される.pollsディレクトリの構造は以下の通り.
polls/
__init__.py
models.py
tests.py
views.py
Djangoにおけるdatabase(を使う)Webアプリを書くための最初のステップはモデルを定義することである.
このチュートリアルではPollとChoiceの二つのモデルを作る.
from django.db import models class Poll(models.Model): question = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): poll = models.ForeignKey(Poll) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)
各クラスのフィールド(CharField, DateTimeField等)はFieldクラスのインスタンスを表している.そしてFieldインスタンスの名前(questionやpub_date)はクラスのフィールド名であり,Pythonコード中で参照可能であり,かつDBのテーブルの列名も兼ねている.
モデルの有効化
model.pyにモデルを記述すると以下のことが出来るようになる.
でも最初にやることはsettings.py
中のINSTALLED_APPSに新規作成したPollsアプリを登録すること.やり方は以下の通り.
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # Uncomment the next line to enable the admin: # 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', 'polls', )
そうすると以下のコマンドを実行してDBスキーマ用のSQL文を確認出来る.
python manage.py sql polls
注意点として,sql
コマンドは実際にSQLを実行する訳ではなく,あくまでもDjangoがこのアプリに必要なSQL文はどんなものかを確認するためのものである.実際にdatabase上で実行させるにはもう一度syncdb
コマンドを実行すればよい.
python manage.py syncdb
APIで遊ぶ
Djangoのshell
コマンドを実行するとDJANGO_SETTINGS_MODULE環境変数をセットした状態でpythonのインタプリタを起動出来る.こうするとDjangoのディレクトリや自分で作成したアプリへのパスが通った状態となるので,コマンドラインで色々な動作チェックが可能となる.
python manage.py shell
どんなことが出来るかはドキュメントを参照のこと.
RFCの検索のしかた
数年前に学校で教えてもらったRFCの効果的な検索の仕方を備忘録としてメモしておく.今時なら検索エンジンに調べたい対象キーワードと"rfc"の二つのキーワードで検索すれば殆どの場合すぐにRFCにたどり着くとは思うが,本家であるIETFサイトから検索する方法も知っているとちゃんと調べました感が高まって良いこともあるかもしれないと思う.
手順(といっても大したことはないが)は以下の通り.
- IETF(The Internet Engineering Task Force)のサイトへとぶ
- 左のナビゲーション領域で"RFC Pages"というリンクでRFCのページへとぶ
- 中段あたりの"RFC Index (Text)"というリンクをクリックする.これはテキストファイルで,RFC 0001から順番にタイトルと著者と年とステータスが一覧で見れる.ここで何かキーワードを使ってテキスト検索すると多分直ぐに対象のRFCの番号が見つかるはず
- RFCの番号をコピーするなりして記憶しておき,再度RFCのページに戻る
- そうしたら検索用テキストボックスにその番号を入力して「search」ボタンを押す
- めでたく該当RFCが検索結果として出てくる.ここからテキストやPDF等の各種フォーマットで閲覧するリンクがあるので,好きなように見る
DBにおける主索引(Primary index)と二次索引(Secondary index)の違い
DBの本を読んでいて,主索引と二次索引という用語について最近までちゃんと理解できていなかった.今の解釈が本当に正しいかは確証は無いが,多分こういうことだろうといえる程度には納得したので,備忘録として書いておく
主索引
テーブルのレコードは実際にディスクに何らかの形で格納されるが,その時に単純なヒープファイルを使うことはほとんど無く,大体は検索効率を考慮して索引を持つファイル編成がとられるはず(例えばB-tree,ハッシュファイル等).で,このように実際のデータを格納するために用いたファイル編成時の索引(キー)が主索引である.
※例えば,テーブルを作成するときに主キーを指定し,その主キーを索引キーとしてBtree構造のファイル編成を採用した場合,主索引(のキー)はその主キーとなる.
二次索引
SQL等を通じてDBに問い合わせる時,上記の主索引キー以外のキーを検索に用いること*1も普通にあるが,そのようなキーで作成した索引が二次索引となる.二次索引も索引というデータを持つのでファイルとしてディスクに保存されるのであるが,二次索引のデータファイルには実際のレコード(の実体)は持たない(主索引のデータファイルで持っているので二重で持つことになり無駄).その代わりに主索引で作成したデータファイル中のレコードへのポインタを持つ.しかも二次索引のキーでは,レコードを一意に識別できないこともある*2ので,レコードへのポインタは複数持つことが多い.
Gitのリモートブランチ操作
Eclipse上のEGitとローカルマシン上のワーキングリポジトリとgithub上のリモートリポジトリ間のコードの連携が訳分からなくなりそうだった.下記のURLが大変参考になった.感謝です.
http://yoshimov.com/?page=Git%2F%A5%EA%A5%E2%A1%BC%A5%C8%A5%D6%A5%E9%A5%F3%A5%C1%A4%CE%CA%D1%B9%B9
目指すところの人たち
自分が目指している領域(レベルや分野)にいる人達をみるとみんな大体高学歴だ.高学歴じゃないとその領域に行けないというわけではないが,確率は間違いなく高くなる.あくまでも確率の話なので,別に学歴が無くてもそういった領域にいる人もいるだろうが,自分が直接的・間接的に知った凄いと思う人達は全員高学歴だった.
自分も社会人になってからもう一度勉強し直そうと学校に通ったりしたが,周りの人には「今更行ってどうする」や「勉強して何の役に立つ」等と言われていた.
勉強が仕事の役に立つ最大の理由というのは,思うに,応用のための基礎知識が身に着くということではないだろうか.オンラインで閲覧できるシラバスや個人的に知り合った当事者たちと話しを総合して自分なりに解釈すると,(特に上位ランク大学の)情報系学科ではプログラミング言語の細かい文法規則等を手取り足取り教わることはあまりないようだが,プログラミング言語を用いて学ばせたい主題(計算機科学的なもの)についてはしっかり教えているという印象がある.
そういう教育の仕方が有効かなと自分でも思うのだが,その理由としては
- 学校では言語の文法等は軽く一通り触る程度で、言語理論や形式的な考え方をじっくり教える
- プログラム言語はあくまでも教えたいことを教えるための道具的な位置づけ。
- それでもそうした抽象的な教え方の方が実は自分で考えることを要求されるため、一階層上の事(メタ知識というか何というか..)が学べて結果的にプログラム言語の理解が深まる
あたりが今思いつくところである.
一方,プログラミングをあまりやったことが無いような新卒達がエンジニア職として入社してくるIT系会社では,最初の数カ月でC言語やJava等の1つの言語を(訳も分からず)こと細かに指導を受ける.しかも1日とか数日で特定の言語の文法を一通りやったりするので,その後すぐにでも使う機会がない限り多分すぐ忘れる.じっくり自分の中で咀嚼する時間もなく次から次へと課題が変わっていき,表面的なことを聞いただけで勉強したでしょう扱いされる.これでは現場に配属されてもすぐには使えないのは当たり前でしょう.
繰り返しになるが,世の中で注目されるようなソフトウェアを作る人達はかなりの高確率で高学歴だと思う.これはつまり,世の中で注目されるようなソフトウェアを作りたかったら,高学歴な人を雇うのはかなり有効な手段だということである.自分の会社をその他大勢の一つではなく,この業界で存在感のある骨太な会社にしたいのなら,高学歴な連中を採用するような戦略をとるのは良い方法の一つではないだろうか.