Ajaxに悩んだ二年間

現代のWeb PageはAjax通信を用いてページの書き換え無しに表示データを更新する仕組みが広く使われています。Ajax = Asynchronous JavaScript and XMLという訳の分からない言葉の頭文字をつなげた造語です。Ajaxが提唱されたのは、古く Internet Explorer5.0の時代に遡ります。ここいら辺に関しては、やはり Microsoft社とIBM社の功績が大きいようです。このIBMのエンジニアが投稿されたブログに詳しく書かれています。

僕もjQueryを用いてこのAjaxという仕組みを用い、データをデータベースから読み出しそれを用いてホームページのDOMを書き換え、動的にページを画面更新無く刷新するようなページをいくつも作成してきました。実はこれもIBMのエンジニアのブログを読んで出来るようになったのです。

さて、jQuery + PHP + MySQLを用いたAjaxはこれまでに色々なサイトで作成してきました。そのほとんどは期待した通りに動作してきたのですが、一つだけ躓く場面があったのです。現在の鎌倉ライブHpは2017年に原型を作り、それを踏襲してきたのですが、基本的概念は、Web上のMySQL databaseにデータを入力して、ユーザー・ページではその databaseからデータを読み出してHpに反映する、そのようにしたのです。

もちろん DBにデータ入力する時にはPWで保護された部分にアクセスし、一般ではアクセスできないようにしています。この時問題となったのは、下記のプログラム部分です。それが不思議なことにうまく行ったり、行かなかったりするのです。

 function ajax_search() {
$( "#search_results" ).show();
var search_val = $( "#search_term" ).val();

$.post( "tri_chair_mod_add01new_backend.php", {
    search_term: search_val
}, function ( data ) {
    if ( data.length > 0 ) {
        $( "#search_results" ).html( data );
    }
} );

  }

これが時にうまく動作して時に動作しないのです。この原因についてどうしても難しすぎて分からなかったのですが、色々考えている内に、Ajaxとは Asynchronous (=非同期)とうのが本質だと思ったのです。Web pageは非同期で表示していかないとユーザーが待たされることになります。ですから、ある画面を描く時にも、あるいはデータを受け取る時にもどちらかがどちらかの完了を待つ(=同期)することが無く、どんどん進んで行くのです。これが原因ではないかと思いました。そこで以下のように変更したのです。

  function ajax_search() {
$( "#search_results" ).show();
var search_val = $( "#search_term" ).val();
        $.ajax({
            type: 'POST',
            url: "tri_chair_mod_add01new_backend.php",
            dataType: 'html',
            data: {
                search_term: search_val
            },
            async: false,
            success: function(data) {
                if ( data.length > 0 ) {
       $( "#search_results" ).html( data );
                }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                alert("Ajax error happened!");
            }
        });
  }

つまり、Ajaxのdefaultである async: trueというのを敢えて async: falseにしたのです。つまり同期をとるようにしたのです。これで長年の懸案が解決しました。とっても難しい概念です。

jQuery libraryの読み込み判定

jQueryや bootstrapは CDNよりそのソースコードを読み込むのが常道です。これには理由があり、まず CDNはライブラリ読み込みに最適化されているので、自分のサーバーから読み込むよりも早い、そしてCDNより読み込めば プログラムの置かれている階層によらず読み込み先を変更する必要が無い、というものです。

ただ、localhostでインターネット接続せずにプログラムを書いていると CDNから読み込めずにプログラムが作動しなくなることもあります。localhostで開発している時にはこれでは困ります。そんな時に、インターネット接続しているか否かで自動判定すれば助かります。そのコードとしては、

 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>if (jQuery) document.write('<script src="lib/jquery.js"><\/script>');</script>

としたり、あるいは jQueryが既に読み込まれているか否かの判定として以下のようにするか

<script>window.jQuery||document.write('<script src="lib/jquery.js"><\/script>');</script><

とするか、あるいは phpを走らせて

<?php
  if ($_SERVER['SERVER_NAME'] === 'locallhost'
?>

として localhostかどうかを判定する、という方法がありますね

.bash_profileが反映されない!!

先日来 terminalの挙動がおかしくなっていました それは根本的には .bash_profileが反映されない、というものでした
したがって、たとえば composerにより laravel/installerをインストールしても、それが反映されないのです。正確に言えば、もっと訳の分からない挙動を示していいたのです
つまり、

$composer global require "laravel/installer"

として MacOSに Laravel installerをインストールします。そうすると bashの設定ファイル ~/.bash_profileの最後にきちんと以下の一文が書き込まれます

export PATH="/Users/******/.composer/vendor/bin:$PATH"

これにより terminalを再起動すれば、その部分も読み込まれ

$echo $PATH

とすれば、きちんと環境変数 PATHに追加されている筈です!

ところが、これが反映されないのです 何でだ??? もちろん

source ~/.bash_profile

として明示的に.bash_profileを読み込ませれば反映されますが、そうせねば反映されないのです。これは bashが壊れたか? とまじに思いました。

しかし、発見しました ネットでは見つけられなかったので誰か困っている方もおられると思いますのでここに記録しておきます。

ターミナルのメニュー
ターミナルのメニューから環境設定を選択する
環境設定メニュータブからシェルを選択
環境設定メニュータブからシェルを選択
シェルタブ選択すねると、「シェル無いで実行」というチェックボックスがある
シェルタブ選択すねると、「シェル無いで実行」というチェックボックスがある

このチェックボックスをチェックするとシェル内で新たなまっ更なシェルが立ち上がる感じで、~/.bash_profileが読み込まれません!!!

なんとなんとこんなオプションがあったなんて!!!

 

ようやく前に進めました

入門Haskellプログラミングを読みながら Haskellの勉強を未だに続けています 何回も何回も挫折の連続ですが、ようやくサンプル・プログラムが作動しました

 

— $stack ghci addressLetter.hs で読み込む
— そして以下のようにこの関数を呼び出すと出力が適切に変化する
— *Main> addressLetter (“Bob”, “Jones”) “sf”
— “Bob Jones – PO Box 1234 – San Francisco, CA, 94111”
— *Main> addressLetter (“Bob”, “Jones”) “ny”
— “Bob Jones : PO Box 789 – New York, NY, 10013”

  

addressLetter name location = locationFunction name
  where locationFunction = getLocationFunction location

  

sfOffice name = if lastName < “L”
                then nameText
                  ++ ” – PO Box 1234 – San Francisco, CA, 94111″
                else nameText
                  ++ ” – PO Box 1010 – San Francisco, CA, 94109″
  where lastName = snd name
        nameText = (fst name) ++ ” ” ++ lastName

  

nyOffice name = nameText ++ ” : PO Box 789 – New York, NY, 10013″
  where nameText = (fst name) ++ ” ” ++ (snd name)
renoOffice name = nameText ++ ” – PO Box 456 – Reno, NV 89523″
  where nameText = snd name

  

getLocationFunction location = case location of
                               “ny” -> nyOffice
                               “sf” -> sfOffice
                               “reno” -> renoOffice
                               _ -> (\name -> (fst name) ++ ” ” ++ (snd name))
  

このようなプログラムです 本からコピーしましたが、HaskellではPythonのようにインデントにも論理的に重要な意味があり、それを間違えると作動しませんし、compileもできません 何回はねられましたが最後に動作しました 出力例もコメントに記載しています

だいぶん頭脳が Haskell脳になってきました

最近感じるのですが、これまでの半年間以上に渡る苦闘の末に、いやまだまだ末ではないのですが、自分の思考がなんだか変わりつつあるのを自覚するようになってきました。要するに Haskell脳になってきているのです。もっともその道のプロの方から見れば「赤ちゃん」のように幼稚な脳でしょうが、それでも変わりつつあります。

そのように自覚するのは、別に Haskellの勉強をしたり、プログラムを書いたりしている時ではないのです。日常生活で、フト今までとは違った思考をしているのに気づくのです。ようやくここまで来ました

-- Haskellで書いた
--リストより先頭文字が一致した項目
--を削除するプログラム
-- remove0.hs

remove' hanbetsu [] = []
remove' hanbetsu (x:xs) = if hanbetsu x
                          then remove' hanbetsu xs
                          else x:remove' hanbetsu xs

test_array = ["apple", "banana", "avogado"]

このソースコードは remove0.hsとしてセーブされています。
これでターミナルから以下のように打ち込みます

$stack ghci

これによりHaskell Interpreterが立ち上がりますので以下のようにプログラムのソースコードである remove0.hs

Prelude>:l remove0.hs

とすることによりコンパイルされますそして

Main>remove' (\(x:xs) -> x == 'b') test_array

とすることにより”banana”のみ無くしたリストが得られます。

まだまだ分からないことだらけ

今朝実は北京経由で西安に入ります それで早朝ですが、突然 node.jsをインストールしようと思いました こんなものとうの昔にインストールしてあった筈ですが、さっきひょんなことで homebrewをアンインストーるして、再びインストールしたのです。そんな訳で homebrewでインストールしてあった node.jsも消えてしまったのです。

「うん? どうやれば node.jsインストールできるんだっけ?」

そこで google博士に聞いて見ました ここにヒットし、とても最近の uploadなのでこれが最高!と思いましたね、そして指示に従いインストールしたのです キモは最後の最新の node.jsをインストールするというこのコマンドです

$nodebrew install-binary latest

ところが、これがエラーが出てどうしてもインストールできないのです。sudoにより権限昇格しても駄目なのです!! 結構こんな時の僕の気分は深海の如く deep blueとなりますね。

それでもやはり朝でした 未だ元気な僕でした ふと思ったのです 何でこんなコマンド入れるのかな? もっと素直に

$brew install node

で良いのでは?

そこでやったところ一発で node.jsがインストールされ、今現在僕のターミナルでは

$node -v
v12.0.0

という具合に最新 node.jsが戻ってきます やったね!!!

僕のbashに一体全体何が起こったのか?

昨日TAVI三例とMitraClip一例の合間に突然のごとく気がついたのです また Visual Studio Code (VS Code)上でかんたんなHaskell programをテストがてらに書いていて、それを VS Codeのターミナルで走らせようと思ったところ、なんとなんと VS Codeターミナル画面から command promptが消失しているのです

これって、要するにコマンド打ち込めません $stack ghc ****.hsとして Haskellプログラムをコンパイルしようとても、なにせその $ が無いのです!!!

まさか、と思い Macのターミナルを立ち上げるとここにも $が無いのです これは大変な事態になりました 何も悪いことはしていません それなのに突然そんなことになったのです 前日はそんなことありませんでした

ひょっとして bashでなく zshでは大丈夫では? と zshを $より立ち上げようとするのですが何しろその $が無いっ!!

きっと、~/.bashあるいは ~/.bash_profileという bashの設定ファイルが壊れたためか? と思いそれを何とか VS Codeの「開く」という graphical interfaceで開こうとしても、今度は 隠しファイル(先頭に .がついたファイルで通常の Macからは見ることも存在も知ることができないファイル)を調べようとしても、何しろそれが見れないのです。そこで、今度は「コマンド」+「シフト」+「.」を押したところ、隠しファイルを見ることができましたので、それで両方の設定ファイルを調べても何も変わっていないのです

今度はとりあえず、「ターミナル」の「環境設定」から立ち上がりシェルを zshに変更し、とりあえずターミナルで zshを立ち上げそれにより操作をしました。まずは、この環境設定から、zsh上で $/bin/bash –version により現在のシステムbashの versionを調べると version 3.2.57(1)となっていました

これは MacOS Mojaveをインストールすると立ち上がる bashですが、何しろ現在の bashは version 5.0.11なので相当に古いものです

そこで次にzshより立ち上がるコマンドをbashにしたのです そして、homebrewで最新の bashをインストールしました

これにより $which bashとすると /usr/local/bin/bashとなり、bash –versionも version 5.0.11となりました

今は訳のわからないままこの状態で動かしています 一体全体何が突然起こったのでしょうか? どなたか Unixに詳しい方教えて下さい

MySQLで DateTime fieldにおいて、年と日付のみ変更する方法

さてそろそろ鎌倉ライブの Web Siteを更新せねばなりません 結構なプログラムが仕込んでありますが、鎌倉ライブのプログラム(予定表)そのものが非常に flexibleですので、Web programmingも結構苦労するのです

2018年のデータを活用するつもりなのですが、これは MySQL databaseに取り込まれている2018年のデータをコピーすれば良いのですが、そこで フト悩んだことが

session_tbls2019の中のbeginTimeというDateTime fieldにコピーされた 2018年データ:: つまりは、”2018-12-15 09:30:00″というようなデータをどうやって2019年データ::つまりは、”2019-12-14 09:30:00″という本年の正しいデータに変換すれば良いのか? これってなかなか難しいですね でも調べました、その結果はこうです SQL文で以下のようにするのです

UPDATE `session_tbls2019` SET `beginDate` = (`beginDate` + INTERVAL -1 DAY);
UPDATE `session_tbls2019` SET `beginDate` = (`beginDate` + INTERVAL +1 YEAR);

これで年と日付が更新されました 便利ですねえっ

WordPressで隠し文章を記録

WordPressでの文章で、ちょっとした trickを思いつきました もう少し暇があれば、Javascriptを用いて動的に画面を作成できるのですが、色々なことを勉強せねばなりません

ここで記載する trickといのは WordPressの文章で cssを用いてあるブロックの文章を表示しなくするのです これと jQueryを組み合わせればボタンをつけてそのボタンにより表示・非表示を切り替えることもできますね

cssはかんたんで style=”visibility: hidden; height:0px;” とするだけなのです でもこれって隠し文章を記録するのに便利ですよっ

Haskellに惑わされ – 13

ライブデモンストレーション開始の直前に理解を深めるために ghciで REPLにより実行しました

Prelude> :{
Prelude| myDiv x = case x of (0, 0) -> 1 :: Int
Prelude|                     (_, 0) -> maxBound
Prelude|                     (n, m) -> n `div` m
Prelude| :}
Prelude> myDiv (0, 0)
1
Prelude> myDiv (100, 0)
9223372036854775807
Prelude> myDiv (3, 5)
0
Prelude> myDiv (100, 2)
50

思いどおりの実行ができましたね もっとも本からの抜粋ですが・・・・ しかし、本に書いているからと言っても簡単に実行できないのが Haskellです 要するにとても「厳しい」言語仕様なのです