Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

hello world

phpとjsとhtmlでhello worldしてみた。

<?php
  //print_r($argv);

function html($content) {
  return "<!DOCTYPE html>\n".wrap("html", $content);
}

function wrap($title,$content, $options=null) {
  if ($options == null) {
    return "<$title>\n"."       ".$content."</$title>\n";
  } else {
    $res = "";
    foreach($options as $key => $value) {
      $op = "$key"."="."$value";
      $res = $res.$op;
    }
    return "<$title $res>\n"."       ".$content."</$title>\n";
  }
}

function head($content) {
  return wrap("head", $content);
}

function body($content) {
  return wrap("body", $content);
}

function script($content) {
  return wrap("script", $content, array("type" => "text/javascript"));
}

function p($content) {
  return wrap("p", $content);
}

// --------------------------------------------
$head = head("
    <title>title</title>
    <meta charset='utf-8' />
    <style type='text/css'>
    p {
      color: yellow;
      background-color: black;
    }
    </style>
  ");

$script = script("
 document.writeln('<p> Hello rorld</p>');
 ");

$body = body(p("Hello World").$script);

$result = html($head.$body);
echo $result;

?>

実行すると以下が表示される。

<!DOCTYPE html>
<html>
       <head>
       
    <title>title</title>
    <meta charset='utf-8' />
    <style type='text/css'>
    p {
      color: yellow;
      background-color: black;
    }
    </style>
  </head>
<body>
       <p>
       Hello World</p>
<script type=text/javascript>
       
 document.writeln('<p> Hello rorld</p>');
 </script>
</body>
</html>

継続モナドその2

APIをFutureで返す。bindはとりあえず省略。

@interface Future<V> : NSObject
- (void)get:(void(^)(V))cb;
@end


@interface API<I,O> : NSObject
- (Future<O> *)getAPI:(I)input;
@end

typedef void(^CallBack)(id);
typedef void(^CPS)(CallBack);

@interface Future()
@property (nonatomic) CPS cps;
@end

@implementation Future

- (instancetype)init:(CPS)cps {
    self = [super init];
    if (self) {
        self.cps = cps;
    }
    return self;
}

- (void)get:(void (^)(id))cb {
    self.cps(cb);
    self.cps = nil;
}

@end

@implementation API
- (Future *)getAPI:(id)input {
    CPS cps = ^(CallBack cb) {
        return cb(input);
    };
    Future *future = [[Future alloc] init:cps];
    return future;
}
@end


Shell

チュートリアルを参照した。
コンソールツール、シェルとタスク - 3.x

src/Shell直下にHelloShell.phpを作る。

<?php
namespace App\Shell;

use Cake\Console\Shell;

class HelloShell extends Shell
{
    public function main()
    {
        $this->out('Hello world.');
    }

    public function heyThere($name = 'Anonymous')
    {
      $this->out('Hey there ' . $name);
      $this->_hoge();
    }

    // _が先頭にあるものは呼べない。
    public function _hoge()
    {
      $this->out('hoge');
    }
}
?>

実行は

./bin/cake hello

./bin/cake Hello hey_there name

等でできる。

bakeもできる。

 ./bin/cake bake shell User

Composer

依存ライブラリ管理ツール。

ライブラリの依存関係を定義する。

ライブラリの依存関係をcomposer.jsonで定義する。

プロジェクトの依存関係を作るには

composer init

で対話的にcomposer.jsonが作れる。

cakephpのプロジェクトを作りたいときは

composer create-project --prefer-dist cakephp/app myproj2

Migrationの失敗

Exception: There was a problem connecting to the database: SQLSTATE[HY000] [2002] No such file or directory in [/Applications/MAMP/htdocs/hoge/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/MysqlAdapter.php, line 115]

のようなエラーに悩まされた。

結果、app.iniのデータベース設定がlocalhostだとダメで、127.0.0.1でうまくいった。また、MAMPのpreferenceでMySQLのポートを調べて、それをapp.iniのデータベースのポート指定に反映させた。

毎回環境設定で躓くのをなんとかしたい。。あとphpのプリントデバッグはprint_rが使える。

カスタムメニュー

つかったことがないが。。

    override func viewDidLoad() {
        super.viewDidLoad()

        UIMenuController.shared.arrowDirection = .right;
        UIMenuController.shared.menuItems = [UIMenuItem.init(title: "a", action: #selector(hello))]
        let r = CGRect(x: 0, y: 0, width: 40, height: 40)
        UIMenuController.shared.setTargetRect(r, in: self.view)
        
        UIMenuController.shared.setMenuVisible(true, animated: true);
       
        UIMenuController.shared.update()
    }
    
    func hello() {
        print("hello")
    }

    
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if (action == #selector(hello)) {
            return true
        }
        return false
    }

カスタムビューのXCode表示

@IBDesignable class MyView: UIView {

    @IBInspectable var cornerRadius : CGFloat = 0.0;
    
    
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
        self.layer.cornerRadius = cornerRadius
        if cornerRadius > 0 {
            self.clipsToBounds = true;
        }
    }
    

}

木構造的なもの

LISPのようなものを作ろうとしたら単に文字列の結合を木構造でやるということになっていた。でもクラスについてだいぶ勉強になった。

//
//  RDLisp.hpp
//  RDLisp
//
//  Created by KatagiriSo on 2017/09/26.
//  Copyright © 2017年 RodhosSoft. All rights reserved.
//

#ifndef RDLisp_hpp
#define RDLisp_hpp

#include <iostream>
#include <stdio.h>

namespace RDLisp {
    
    template<class T>
    using Share = std::shared_ptr<T>;

    
    class Printable {
    public:
        virtual std::string description() = 0;
    };
    
    
    class S : public Printable{
    public:
    };
    
    class Value;
    
    class Pair : public S {
    public:
        Share<S> car;
        Share<S> cdr;
        Pair(Share<S> car, Share<S> cdr) {
            this->car = car;
            this->cdr = cdr;
        }
        
        std::string description();
        bool isFunc();
        bool isValue();
    };
    
    
    class Nil : public S {
    public:
        Nil();
        std::string description();
    };
    
    class Symbol;
    class Value;
    
    class Atom  : public S {
    public:
        std::string value;
        Atom(std::string value) {
            this->value = value;
        };
        std::string description();
    };
    
    
    class Value : public Atom {
    public:
        Value(std::string value) : Atom(value) {
            
        };
    };
    
    /// symbol is function
    class Symbol : public Atom {
    public:
        Symbol(std::string value) : Atom(value) {
            
        };
    };
    

    Share<S> eval(Share<S> s);
    Share<S> apply(Share<Symbol> sy, Share<S> target);
}



#endif /* RDLisp_hpp */
//
//  RDLisp.cpp
//  RDLisp
//
//  Created by KatagiriSo on 2017/09/26.
//  Copyright © 2017年 RodhosSoft. All rights reserved.
//

#include "RDLisp.hpp"

#include <vector>
#include <string>

namespace RDLisp {
    
    template <class T>
    Share<T> scast(Share <S> s) {
        return std::dynamic_pointer_cast<T>(s);
    }
    
    Share<Value> add(Share<S> target, int n) {
        std::cout <<std::string(n, ' ') << "+"<< "\n";

        if (auto v = scast<Value>(target)) {
            std::cout << std::string(n, ' ')<< v->description() << "\n";
            return v;
        }
        
        if (auto p = scast<Pair>(target)) {
            
            if (auto s = scast<Symbol>(p->car)) {
                auto cdr_after = apply(s, p->cdr);
                if (auto v = scast<Value>(cdr_after)) {
                    return v;

                } else {
                    return nullptr;
                }
            }
            
            if (auto f = scast<Value>(p->car)) {
                auto l = add(p->cdr, n+1);
                if (f&&l) {
                    auto v = std::make_shared<Value>(f->value + l->value);
                    
                    std::cout <<std::string(n, ' ')<< "["<< v->description() << "]"<< "\n";
                    return v;
                } else {
                    return nullptr;
                }
            }
            
            if (auto l = scast<Value>(p->cdr)) {
                auto f = add(p->car, n+1);
                if (f&&l) {
                    auto v = std::make_shared<Value>(f->value + l->value);
                    
                    std::cout <<std::string(n, ' ')<< "["<< v->description() << "]"<< "\n";
                    return v;
                } else {
                    return nullptr;
                }
            }
            
            
            auto f = add(p->car, n+1);
            auto l = add(p->cdr, n+1);
            if (f&&l) {
                auto v = std::make_shared<Value>(f->value + l->value);
                
                std::cout <<std::string(n, ' ')<< "["<< v->description() << "]"<< "\n";
                return v;
            } else {
                return nullptr;
            }
        }
        
        std::cout <<std::string(n, ' ')<< "nullptr"<< "\n";
        return nullptr;
    }
    

    
    Share<S> eval(Share<S> exp) {
        auto pair = scast<Pair>(exp);
        if (pair) {
            if (pair->isFunc()) {
                auto sy = std::dynamic_pointer_cast<Symbol>(pair->car);
//                auto crd_after = eval(pair->cdr);
//                std::cout << "crd_after" + crd_after->description() + "\n";
                return apply(sy, pair->cdr);
//                return apply(sy, crd_after);

            }
        }
        
        return exp;
    }
    
    Share<S> apply(Share<Symbol> sy, Share<S> target) {
        
        if (sy->value == "+") {
            if (auto v = scast<Value>(target)) {
                return target;
            }
            
            if (auto p = scast<Pair>(target)) {
                auto exp = add(target, 0);
                if (exp) {
                    return exp;
                }
            }
            
        }
        
        return std::make_shared<Pair>(sy,target);
    }

    
    bool Pair::isFunc() {
        auto sy = std::dynamic_pointer_cast<Symbol>(this->car);
        if (sy) {
            return true;
        }
        return false;
    }
    


    
    std::string Pair::description() {
        return "(" + this->car->description() + " " + this->cdr->description() + ")";  
    }
    
    std::string Atom::description() {
        return this->value;
    }

    std::string Nil::description() {
        return "";
    }

    

}

実行は次のようにする。面倒。

//
//  main.cpp
//  RDLisp
//
//  Created by KatagiriSo on 2017/09/26.
//  Copyright © 2017年 RodhosSoft. All rights reserved.
//

#include <iostream>
#include "RDLisp.hpp"

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    
    using namespace RDLisp;
    using namespace std;
    
    auto a1 = make_shared<Value>("a1");
    auto a2 = make_shared<Value>("a2");
    auto pair_a = make_shared<Pair>(a1,a2);
    auto b = make_shared<Value>("b");
    auto c = make_shared<Value>("c");
    auto d = make_shared<Value>("d");
    auto add = make_shared<Symbol>("+");
    auto add2 = make_shared<Symbol>("+");
    auto pair_ab = make_shared<Pair>(pair_a,b);
    auto pair_cd = make_shared<Pair>(c,d);
    auto pair = make_shared<Pair>(add, pair_ab);
    auto pair2 = make_shared<Pair>(add, pair_cd);
    auto pair3 = make_shared<Pair>(pair, pair2);
    auto pair4 = make_shared<Pair>(add2, pair3);
    
    std::cout << pair4->description() << "\n";
    
    auto res = eval(pair4);
    
    std::cout << res->description() << "\n";

    
    return 0;
}

結果は

Hello, World!
(+ ((+ ((a1 a2) b)) (+ (c d))))
+
 +
+
 +
  +
  a2
 [a1a2]
[a1a2b]
 +
+
 +
 d
[cd]
[a1a2bcd]
a1a2bcd
Program ended with exit code: 0