Proxy dynamique avec python, ruby, PHP

introduction

Cet article est le 20ème jour du "Calendrier de l'Avent WACUL 2016". Récemment, j'ai personnellement relu le ruby de méta-programmation et l'ai utilisé en partie au travail ~~ Il n'y a pas de nouveau matériel à parler ~~, donc cette fois je vais écrire sur le proxy dynamique.

Qu'est-ce qu'un proxy dynamique?

En fait, je ne sais pas à quel point ce mot est courant ... Personnellement, "un modèle de programmation qui reçoit le nom et les paramètres d'une méthode non définie et délègue le traitement souhaité à un autre objet" Je reconnais cela.

Quand utiliser

Ceci est utile lorsque vous souhaitez écrire un wrapper pour un système externe.

Par exemple, supposons que vous souhaitiez écrire une bibliothèque cliente qui utilise une API REST externe. Par souci de simplicité, limitons-nous à GET.

GET /api/hoge

Pour exécuter, par exemple, en utilisant des requêtes en python

import requests

class Client:
    def hoge(self):
        return requests.get('/api/hoge')

client = Client()
client.hoge()

Etc. Rien n'est difficile. Cependant, dans ce cas, si le fuga, le piyo, etc. augmentent

class Client:
    def hoge(self):
        return requests.get('/api/hoge')
    def fuga(self):
        return requests.get('/api/fuga')
    def piyo(self):
        return requests.get('/api/piyo')

C'est difficile car le nombre de copies augmente.

Par conséquent, nous utilisons "une méthode spéciale qui est appelée lorsqu'une méthode ou une propriété est introuvable". Dans le cas de python, __ getattr__` peut être utilisé car les méthodes et les propriétés sont les mêmes et les attributs de l'objet.

class Client:
    def __getattr__(self, name):
        def _func(*args, **kwargs):
            return requests.get('/api/' + name)
        return _func

Vous pouvez maintenant prendre en charge client.hoge (), client.fuga () et client.piyo (), et le meilleur de tous, vous n'avez pas besoin de maintenir la classe Client car d'autres API seront ajoutées à l'avenir. De plus, en fonction de l'implémentation de `` _func```, vous êtes libre de gérer les paramètres que vous passez à client.method.

Proxy dynamique avec Ruby et PHP

Tout d'abord, faisons-le en Ruby. Cette fois, j'utiliserai method_missing car je veux non seulement réduire la quantité de code mais aussi correspondre dynamiquement à des spécifications inconnues.

a.rb


class A
  def method_missing(name, *args, &blk)
    p name.to_s
    p args
    return if not block_given?
    blk.call
  end
end

a = A.new
a.hoge
a.fuga(1, 2, 3)
a.piyo do |i, j|
  p "piyopiyo"
end

Quand vous l'exécutez, ça ressemble à ça

"hoge"
[]
"fuga"
[1, 2, 3]
"piyo"
[]
"piyopiyo"

Vient ensuite PHP. Utilisez `__ call `. Je m'en souvenais quand j'écrivais au travail ~~ quand c'était écrit ~~. Cela fait du bien lorsqu'il est combiné avec Reflection. Pour les méthodes statiques, il existe une autre méthode appelée `` __callStatic```.

a.php


<?php

class A
{
    public function __call($name, $args)
    {
        var_dump($name);
        var_dump($args);
    }
}

$a = new A();
$a->hoge();
$a->fuga("fugaarg");

Quand je le lance avec cli, ça ressemble à ça

string(4) "hoge"
array(0) {
}
string(4) "fuga"
array(1) {
  [0]=>
  string(7) "fugaarg"
}

Faites attention

Si vous l'utilisez trop, le code a tendance à être difficile à lire. Utilisez-le systématiquement.

Recommended Posts

Proxy dynamique avec python, ruby, PHP
Réaliser un générateur PHP / Python avec Golang / Ruby
J'ai essayé d'utiliser mecab avec python2.7, ruby2.3, php7
Java VS PHP VS Python VS Ruby
Zundokokiyoshi avec python / rubis / Lua
À propos de Perl, Python, PHP, Ruby
Résolution avec Ruby et Python AtCoder ABC178 D Méthode de planification dynamique
Scraping avec Node, Ruby et Python
Combinaisons qui se chevauchent avec des limites supérieures en Python / Ruby / PHP / Golang (Go)
Résolution avec Ruby et Python AtCoder ABC011 C Méthode de planification dynamique
Résolution avec Ruby et Python AtCoder ABC153 E Méthode de planification dynamique
Gestion des expressions régulières par PHP / Python
Envoyer l'image avec python et enregistrer avec php
Exemple PHP / Python / Ruby frappant l'API Path
[Grammaire de base] Différences entre Ruby / Python / PHP
Essayez d'appeler Python depuis Ruby avec une économie
Crypter avec Ruby (Rails) et décrypter avec Python
Scraping Web facile avec Python et Ruby
FizzBuzz en Python3
Grattage avec Python
Statistiques avec python
Grattage avec Python
Python avec Go
Twilio avec Python
Typage dynamique de Python
Intégrer avec Python
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
python commence par ()
avec syntaxe (Python)
Bingo avec python
Zundokokiyoshi avec python
J'ai essayé de frapper l'API Mastodon avec Ruby (Faraday) / Python (Pycurl) / PHP (Curl)
Excel avec Python
Micro-ordinateur avec Python
Cast avec python
[Diverses analyses d'images avec plotly] Visualisation dynamique avec plotly [python, image]
[Écrire sur la carte avec plotly] Visualisation dynamique avec plotly [python]
Combinaison de regroupement en Python / Ruby / PHP / Golang (Go)
Communication série avec Python
Zip, décompressez avec python
Django 1.11 a démarré avec Python3.6
Jugement des nombres premiers avec Python
Python avec eclipse + PyDev.
Tendances 2014 du cadre d'application Web (PHP / Java / Ruby / Python / Perl)
Communication de socket avec Python
Analyse de données avec python 2
Grattage en Python (préparation)
Essayez de gratter avec Python.
Tutoriel [Docker] (Python + php)
Pages HTML dynamiques créées avec AWS Lambda et Python
Apprendre Python avec ChemTHEATER 03
Recherche séquentielle avec Python
"Orienté objet" appris avec python
Exécutez Python avec VBA
Manipuler yaml avec python
Résolvez AtCoder 167 avec python
[Python] Utiliser JSON avec Python
Apprendre Python avec ChemTHEATER 05-1
Apprenez Python avec ChemTHEATER