Comparison returns expected value call function directory, but it is not so at process on list









up vote
1
down vote

favorite












I am creating a simple elisp tester.
However, I am getting the wrong behavior (which I can not understand) as seen below.



I think that testers should return t test cases (:eq 'a 'a) and (:eq (return-symbol) 'a) naturally as my tester also precedes the following code. Actually it is not so.



The following code has been lengthened beyond necessity, but for the most part it is checking the obvious behavior.



I think that my tester should also return those expected return values.



Are there any good ideas?
Even explaining the reason for this behavior would be a help to improve my tester. I would appreciate it if you give me something.



;; return-symbol is always return 'a
(defun return-symbol ()
'a)
;; => return-symbol

;; operation check for return-symbol
(return-symbol)
;; => a

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; compare 'a and 'a by eq
(eq 'a 'a)
;; => t

;; compare 'a and 'a by equal
(equal 'a 'a)
;; => t

;; compare (return-symbol) and 'a by eq
(eq (return-symbol) 'a)
;; => t

;; compare (return-symbol) and (return-symbol) by eq
(eq (return-symbol) (return-symbol))
;; => t

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; comparison by funcalled eq
(funcall 'eq 'a 'a)
;; => t

(funcall 'eq (return-symbol) 'a)
;; => t

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; funcall with interned symbol
(funcall (intern "eq") 'a 'a)
;; => t

(funcall (intern "eq") (return-symbol) 'a)
;; => t

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; define universal comparison function
(defun multi-comp (key a b)
"KEY is funcname symbol such as :FUNCNAME"
(let ((funcname (replace-regexp-in-string "^:+" "" (symbol-name key))))
(funcall (intern funcname) a b)))
;; => multi-comp

;; operation check for multi-comp
(multi-comp :eq 'a 'a)
;; => t

(multi-comp :eq (return-symbol) 'a)
;; => t

(multi-comp :equal (return-symbol) 'a)
;; => t

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Define function to apply sequentially
(defun run-test (tests)
"TESTS is list such as (([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))
([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))...)"
(dolist (x tests)
(let* ((testname (car x))
(values (cadr x))
(key (nth 0 values))
(a (nth 1 values))
(b (nth 2 values)))
(if (multi-comp key a b)
(princ (format "%s is passedn" testname))
(princ (format "%s is failedn" testname))))))
;; => run-test

;; operation check of run-test
(run-test '(("eq1" (:eq 'a 'a))
("eq2" (:eq (return-symbol) (return-symbol)))
("equal1" (:equal 'a 'a))
("equal2" (:equal (return-symbol) 'a))
("equal3" (:equal (return-symbol) (return-symbol)))))
;; =>
;; eq1 is failed ; <= ??
;; eq2 is failed ; <= ??
;; equal1 is passed
;; equal2 is failed ; <= ??
;; equal3 is passed
;; nil









share|improve this question



























    up vote
    1
    down vote

    favorite












    I am creating a simple elisp tester.
    However, I am getting the wrong behavior (which I can not understand) as seen below.



    I think that testers should return t test cases (:eq 'a 'a) and (:eq (return-symbol) 'a) naturally as my tester also precedes the following code. Actually it is not so.



    The following code has been lengthened beyond necessity, but for the most part it is checking the obvious behavior.



    I think that my tester should also return those expected return values.



    Are there any good ideas?
    Even explaining the reason for this behavior would be a help to improve my tester. I would appreciate it if you give me something.



    ;; return-symbol is always return 'a
    (defun return-symbol ()
    'a)
    ;; => return-symbol

    ;; operation check for return-symbol
    (return-symbol)
    ;; => a

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;; compare 'a and 'a by eq
    (eq 'a 'a)
    ;; => t

    ;; compare 'a and 'a by equal
    (equal 'a 'a)
    ;; => t

    ;; compare (return-symbol) and 'a by eq
    (eq (return-symbol) 'a)
    ;; => t

    ;; compare (return-symbol) and (return-symbol) by eq
    (eq (return-symbol) (return-symbol))
    ;; => t

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;; comparison by funcalled eq
    (funcall 'eq 'a 'a)
    ;; => t

    (funcall 'eq (return-symbol) 'a)
    ;; => t

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;; funcall with interned symbol
    (funcall (intern "eq") 'a 'a)
    ;; => t

    (funcall (intern "eq") (return-symbol) 'a)
    ;; => t

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;; define universal comparison function
    (defun multi-comp (key a b)
    "KEY is funcname symbol such as :FUNCNAME"
    (let ((funcname (replace-regexp-in-string "^:+" "" (symbol-name key))))
    (funcall (intern funcname) a b)))
    ;; => multi-comp

    ;; operation check for multi-comp
    (multi-comp :eq 'a 'a)
    ;; => t

    (multi-comp :eq (return-symbol) 'a)
    ;; => t

    (multi-comp :equal (return-symbol) 'a)
    ;; => t

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;; Define function to apply sequentially
    (defun run-test (tests)
    "TESTS is list such as (([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))
    ([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))...)"
    (dolist (x tests)
    (let* ((testname (car x))
    (values (cadr x))
    (key (nth 0 values))
    (a (nth 1 values))
    (b (nth 2 values)))
    (if (multi-comp key a b)
    (princ (format "%s is passedn" testname))
    (princ (format "%s is failedn" testname))))))
    ;; => run-test

    ;; operation check of run-test
    (run-test '(("eq1" (:eq 'a 'a))
    ("eq2" (:eq (return-symbol) (return-symbol)))
    ("equal1" (:equal 'a 'a))
    ("equal2" (:equal (return-symbol) 'a))
    ("equal3" (:equal (return-symbol) (return-symbol)))))
    ;; =>
    ;; eq1 is failed ; <= ??
    ;; eq2 is failed ; <= ??
    ;; equal1 is passed
    ;; equal2 is failed ; <= ??
    ;; equal3 is passed
    ;; nil









    share|improve this question

























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I am creating a simple elisp tester.
      However, I am getting the wrong behavior (which I can not understand) as seen below.



      I think that testers should return t test cases (:eq 'a 'a) and (:eq (return-symbol) 'a) naturally as my tester also precedes the following code. Actually it is not so.



      The following code has been lengthened beyond necessity, but for the most part it is checking the obvious behavior.



      I think that my tester should also return those expected return values.



      Are there any good ideas?
      Even explaining the reason for this behavior would be a help to improve my tester. I would appreciate it if you give me something.



      ;; return-symbol is always return 'a
      (defun return-symbol ()
      'a)
      ;; => return-symbol

      ;; operation check for return-symbol
      (return-symbol)
      ;; => a

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; compare 'a and 'a by eq
      (eq 'a 'a)
      ;; => t

      ;; compare 'a and 'a by equal
      (equal 'a 'a)
      ;; => t

      ;; compare (return-symbol) and 'a by eq
      (eq (return-symbol) 'a)
      ;; => t

      ;; compare (return-symbol) and (return-symbol) by eq
      (eq (return-symbol) (return-symbol))
      ;; => t

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; comparison by funcalled eq
      (funcall 'eq 'a 'a)
      ;; => t

      (funcall 'eq (return-symbol) 'a)
      ;; => t

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; funcall with interned symbol
      (funcall (intern "eq") 'a 'a)
      ;; => t

      (funcall (intern "eq") (return-symbol) 'a)
      ;; => t

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; define universal comparison function
      (defun multi-comp (key a b)
      "KEY is funcname symbol such as :FUNCNAME"
      (let ((funcname (replace-regexp-in-string "^:+" "" (symbol-name key))))
      (funcall (intern funcname) a b)))
      ;; => multi-comp

      ;; operation check for multi-comp
      (multi-comp :eq 'a 'a)
      ;; => t

      (multi-comp :eq (return-symbol) 'a)
      ;; => t

      (multi-comp :equal (return-symbol) 'a)
      ;; => t

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; Define function to apply sequentially
      (defun run-test (tests)
      "TESTS is list such as (([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))
      ([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))...)"
      (dolist (x tests)
      (let* ((testname (car x))
      (values (cadr x))
      (key (nth 0 values))
      (a (nth 1 values))
      (b (nth 2 values)))
      (if (multi-comp key a b)
      (princ (format "%s is passedn" testname))
      (princ (format "%s is failedn" testname))))))
      ;; => run-test

      ;; operation check of run-test
      (run-test '(("eq1" (:eq 'a 'a))
      ("eq2" (:eq (return-symbol) (return-symbol)))
      ("equal1" (:equal 'a 'a))
      ("equal2" (:equal (return-symbol) 'a))
      ("equal3" (:equal (return-symbol) (return-symbol)))))
      ;; =>
      ;; eq1 is failed ; <= ??
      ;; eq2 is failed ; <= ??
      ;; equal1 is passed
      ;; equal2 is failed ; <= ??
      ;; equal3 is passed
      ;; nil









      share|improve this question















      I am creating a simple elisp tester.
      However, I am getting the wrong behavior (which I can not understand) as seen below.



      I think that testers should return t test cases (:eq 'a 'a) and (:eq (return-symbol) 'a) naturally as my tester also precedes the following code. Actually it is not so.



      The following code has been lengthened beyond necessity, but for the most part it is checking the obvious behavior.



      I think that my tester should also return those expected return values.



      Are there any good ideas?
      Even explaining the reason for this behavior would be a help to improve my tester. I would appreciate it if you give me something.



      ;; return-symbol is always return 'a
      (defun return-symbol ()
      'a)
      ;; => return-symbol

      ;; operation check for return-symbol
      (return-symbol)
      ;; => a

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; compare 'a and 'a by eq
      (eq 'a 'a)
      ;; => t

      ;; compare 'a and 'a by equal
      (equal 'a 'a)
      ;; => t

      ;; compare (return-symbol) and 'a by eq
      (eq (return-symbol) 'a)
      ;; => t

      ;; compare (return-symbol) and (return-symbol) by eq
      (eq (return-symbol) (return-symbol))
      ;; => t

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; comparison by funcalled eq
      (funcall 'eq 'a 'a)
      ;; => t

      (funcall 'eq (return-symbol) 'a)
      ;; => t

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; funcall with interned symbol
      (funcall (intern "eq") 'a 'a)
      ;; => t

      (funcall (intern "eq") (return-symbol) 'a)
      ;; => t

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; define universal comparison function
      (defun multi-comp (key a b)
      "KEY is funcname symbol such as :FUNCNAME"
      (let ((funcname (replace-regexp-in-string "^:+" "" (symbol-name key))))
      (funcall (intern funcname) a b)))
      ;; => multi-comp

      ;; operation check for multi-comp
      (multi-comp :eq 'a 'a)
      ;; => t

      (multi-comp :eq (return-symbol) 'a)
      ;; => t

      (multi-comp :equal (return-symbol) 'a)
      ;; => t

      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      ;; Define function to apply sequentially
      (defun run-test (tests)
      "TESTS is list such as (([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))
      ([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))...)"
      (dolist (x tests)
      (let* ((testname (car x))
      (values (cadr x))
      (key (nth 0 values))
      (a (nth 1 values))
      (b (nth 2 values)))
      (if (multi-comp key a b)
      (princ (format "%s is passedn" testname))
      (princ (format "%s is failedn" testname))))))
      ;; => run-test

      ;; operation check of run-test
      (run-test '(("eq1" (:eq 'a 'a))
      ("eq2" (:eq (return-symbol) (return-symbol)))
      ("equal1" (:equal 'a 'a))
      ("equal2" (:equal (return-symbol) 'a))
      ("equal3" (:equal (return-symbol) (return-symbol)))))
      ;; =>
      ;; eq1 is failed ; <= ??
      ;; eq2 is failed ; <= ??
      ;; equal1 is passed
      ;; equal2 is failed ; <= ??
      ;; equal3 is passed
      ;; nil






      lisp elisp funcall






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 7:00









      sds

      38.3k1492166




      38.3k1492166










      asked Nov 11 at 1:38









      Conao3

      76316




      76316






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          Your argument to run-test is evaluated once, so "eq1" sees 'a which is (quote a) (a list of length 2) which is, of course, fails under eq.
          Similarly, (return-symbol) is not evaluated and "eq1" sees the lists of length 1 which are not identical under eq.



          You would have discovered that by simply adding print to multi-comp.



          Your code would probably work is you replace (multi-comp key a b) with (multi-comp key (eval a) (eval b)).



          Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.



          PS. I urge you to use ERT instead of rolling your own.






          share|improve this answer






















          • I misunderstood (multi-comp key (eval a) (eval b)) is error, because (eval 'a) is error. Actuary, (eval a) is (eval ''a), so it returns 'a !! Thank you!
            – Conao3
            Nov 11 at 5:49










          • I know that there is ERT, but I test Emacs-22 to Emacs-26 in same code. So I create new test framework srt.el
            – Conao3
            Nov 11 at 5:53






          • 1




            @NaoyaYamashita: Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.
            – sds
            Nov 11 at 6:01










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53245115%2fcomparison-returns-expected-value-call-function-directory-but-it-is-not-so-at-p%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote



          accepted










          Your argument to run-test is evaluated once, so "eq1" sees 'a which is (quote a) (a list of length 2) which is, of course, fails under eq.
          Similarly, (return-symbol) is not evaluated and "eq1" sees the lists of length 1 which are not identical under eq.



          You would have discovered that by simply adding print to multi-comp.



          Your code would probably work is you replace (multi-comp key a b) with (multi-comp key (eval a) (eval b)).



          Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.



          PS. I urge you to use ERT instead of rolling your own.






          share|improve this answer






















          • I misunderstood (multi-comp key (eval a) (eval b)) is error, because (eval 'a) is error. Actuary, (eval a) is (eval ''a), so it returns 'a !! Thank you!
            – Conao3
            Nov 11 at 5:49










          • I know that there is ERT, but I test Emacs-22 to Emacs-26 in same code. So I create new test framework srt.el
            – Conao3
            Nov 11 at 5:53






          • 1




            @NaoyaYamashita: Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.
            – sds
            Nov 11 at 6:01














          up vote
          3
          down vote



          accepted










          Your argument to run-test is evaluated once, so "eq1" sees 'a which is (quote a) (a list of length 2) which is, of course, fails under eq.
          Similarly, (return-symbol) is not evaluated and "eq1" sees the lists of length 1 which are not identical under eq.



          You would have discovered that by simply adding print to multi-comp.



          Your code would probably work is you replace (multi-comp key a b) with (multi-comp key (eval a) (eval b)).



          Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.



          PS. I urge you to use ERT instead of rolling your own.






          share|improve this answer






















          • I misunderstood (multi-comp key (eval a) (eval b)) is error, because (eval 'a) is error. Actuary, (eval a) is (eval ''a), so it returns 'a !! Thank you!
            – Conao3
            Nov 11 at 5:49










          • I know that there is ERT, but I test Emacs-22 to Emacs-26 in same code. So I create new test framework srt.el
            – Conao3
            Nov 11 at 5:53






          • 1




            @NaoyaYamashita: Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.
            – sds
            Nov 11 at 6:01












          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          Your argument to run-test is evaluated once, so "eq1" sees 'a which is (quote a) (a list of length 2) which is, of course, fails under eq.
          Similarly, (return-symbol) is not evaluated and "eq1" sees the lists of length 1 which are not identical under eq.



          You would have discovered that by simply adding print to multi-comp.



          Your code would probably work is you replace (multi-comp key a b) with (multi-comp key (eval a) (eval b)).



          Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.



          PS. I urge you to use ERT instead of rolling your own.






          share|improve this answer














          Your argument to run-test is evaluated once, so "eq1" sees 'a which is (quote a) (a list of length 2) which is, of course, fails under eq.
          Similarly, (return-symbol) is not evaluated and "eq1" sees the lists of length 1 which are not identical under eq.



          You would have discovered that by simply adding print to multi-comp.



          Your code would probably work is you replace (multi-comp key a b) with (multi-comp key (eval a) (eval b)).



          Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.



          PS. I urge you to use ERT instead of rolling your own.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 11 at 7:02

























          answered Nov 11 at 2:05









          sds

          38.3k1492166




          38.3k1492166











          • I misunderstood (multi-comp key (eval a) (eval b)) is error, because (eval 'a) is error. Actuary, (eval a) is (eval ''a), so it returns 'a !! Thank you!
            – Conao3
            Nov 11 at 5:49










          • I know that there is ERT, but I test Emacs-22 to Emacs-26 in same code. So I create new test framework srt.el
            – Conao3
            Nov 11 at 5:53






          • 1




            @NaoyaYamashita: Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.
            – sds
            Nov 11 at 6:01
















          • I misunderstood (multi-comp key (eval a) (eval b)) is error, because (eval 'a) is error. Actuary, (eval a) is (eval ''a), so it returns 'a !! Thank you!
            – Conao3
            Nov 11 at 5:49










          • I know that there is ERT, but I test Emacs-22 to Emacs-26 in same code. So I create new test framework srt.el
            – Conao3
            Nov 11 at 5:53






          • 1




            @NaoyaYamashita: Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.
            – sds
            Nov 11 at 6:01















          I misunderstood (multi-comp key (eval a) (eval b)) is error, because (eval 'a) is error. Actuary, (eval a) is (eval ''a), so it returns 'a !! Thank you!
          – Conao3
          Nov 11 at 5:49




          I misunderstood (multi-comp key (eval a) (eval b)) is error, because (eval 'a) is error. Actuary, (eval a) is (eval ''a), so it returns 'a !! Thank you!
          – Conao3
          Nov 11 at 5:49












          I know that there is ERT, but I test Emacs-22 to Emacs-26 in same code. So I create new test framework srt.el
          – Conao3
          Nov 11 at 5:53




          I know that there is ERT, but I test Emacs-22 to Emacs-26 in same code. So I create new test framework srt.el
          – Conao3
          Nov 11 at 5:53




          1




          1




          @NaoyaYamashita: Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.
          – sds
          Nov 11 at 6:01




          @NaoyaYamashita: Please note that the fact that you need eval is a very strong indicator that you are doing something horribly wrong.
          – sds
          Nov 11 at 6:01

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53245115%2fcomparison-returns-expected-value-call-function-directory-but-it-is-not-so-at-p%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Barbados

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3