Number of entries: 20

As we saw earlier, Test::Builder is the backbone of the testing framework of Perl. The Test::Simple, Test::More are built on top of this module and there hundreds of other modules in the Test::* namespace on CPAN that use this same back-end. All those modules provide extra testing functionality.

Though actually there are a few modules in the Test:: namespace that are not "testing modules" in the same way as the the ones we are talking about here, but the majority can be loaded in any test script and the majority provide extra testing functions.

As we create is_any, other created lot os other such functions and modules.

Posted on 2016-09-30 08:30:01
http://qiita.com/shuetsu@github/items/ac21e597265d6bb906dc わりとよくある JSON ベースの lisp っぽいインタープリタの実装ですが、コードを見ていてもよくわからなかったので自分で実装しなおしてみました。 ```java package com.example; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import com.fasterxml.jackson.databind.ObjectMapper; public class OreLang { HashMap vars = new HashMap<>(); private Object eval(Object o) { if (o instanceof List) { System.out.println("Running: " + o); Object result = doRun((List) o); System.out.println("Result: " + o + " : " + result + " : " + vars); return result; } else { return o; } } private Object doRun(List list) { String op = (String) list.get(0); List args = list.subList(1, list.size()); switch (op) { case "set": vars.put((String) args.get(0), eval(args.get(1))); return null; case "get": return vars.get(args.get(0)); case "+": return (Integer) eval(args.get(0)) + (Integer) eval(args.get(1)); case "=": return eval(args.get(0)) == eval(args.get(1)); case "until": while (!(Boolean) eval(args.get(0))) { eval(args.get(1)); } return null; case "step": List collect = args.stream() .map(this::eval) .collect(Collectors.toList()); return collect.get(collect.size() - 1); } throw new RuntimeException("Unknown operation: " + op); } public static void main(String[] args) throws IOException { String source = "[\"step\",\n" + " [\"set\", \"i\", 10],\n" + " [\"set\", \"sum\", 0],\n" + " [\"until\", [\"=\", [\"get\", \"i\"], 0], [\n" + " \"step\",\n" + " [\"set\", \"sum\", [\"+\", [\"get\", \"sum\"], [\"get\", \"i\"]]],\n" + " [\"set\", \"i\", [\"+\", [\"get\", \"i\"], -1]]\n" + " ]],\n" + " [\"get\", \"sum\"]\n" + "]\n"; ObjectMapper objectMapper = new ObjectMapper(); Object script = objectMapper.readValue(source, Object.class); Object result = new OreLang().eval(script); System.out.println("RESULT: " + result); } } ```
This week is red stripe week. The red stripe is awarded to students during the 5th week of the cycle. The red stripe is given once a student has turned in their letter of intent to promote and registered for promotion. The student must have earned their yellow, blue, 1st black, and 2nd black stripe […]
Earlier today I saw a recent blog post from Gabor Szabo. In it, he shows a very concise way to handle Basic Authentication using LWP::UserAgent. Now, what if you had a problem running the script? How might you go about debugging it? You could add a bunch of print statements. Maybe dump the request and […]
Hacktoberfest is nearly upon us again. If you sign up and then do 4 pull requests in October, you'll get a free t-shirt. Sadly the list of Featured Projects doesn't include any Perl ones, but last year I created a...
Hey everyone, Following is the p5p (Perl 5 Porters) mailing list summary for the past two weeks. Enjoy!...

A while ago I wrote an article on LWP::UserAgent and Basic Authentication and posted it on Reddit as well, where a user pointed to an even simpler solution, one that I did not find in the documentation myself. It uses LWP::UserAgent and HTTP::Request::Common which is a dependency of LWP::UserAgent anyway.



One of the most beautiful things I’ve ever seen. A journey to the edge of space (90,000+ feet in 360 degrees). 

Dave Mitchell writes: I spent last month mainly working on "fuzzer" bug reports. Nothing really stands out as deserving special mention. Summary 1:23 "Confused by eval behavior" thread 0:14 perl #128940 "Use of uninitialized value $fh" mentions wrong variable 2:48 perl #128951 heap-buffer-overflow in Perl_sv_vcatpvfn_flags 0:51 perl #128952 stack-buffer-overflow in S_missingterm 1:41 perl #128989 Bleadperl v5.25.3-266-g1d7e644 breaks VPIT/Variable-Magic-0.59.tar.gz 4:46 perl #129012 heap-buffer-overflow Perl_fbm_instr 2:04 perl #129029 SIGBUS Perl_sv_peek 0:24 perl #129038 Assertion Failure: *Perl_pp_subst *pp_hot.c:3203 3:45 perl #129064 heap-buffer-overflow S_scan_heredoc...
`@RequestMapping` に `produces = MediaType.APPLICATION_JSON_UTF8_VALUE` を指定したときの効果について。指定すべきかどうなのか # 結論 * つけなくても実害はない * XML シリアライザが依存に入っている場合、`Accept: application/xml` のようにヘッダが入っている場合、XML でレスポンスが返却される。 * ほとんどの場合は produces 指定するかどうか指定するよりも HttpMessageConverter を明示するようにしたほうが良い。 * 公開される API の場合には HttpMessageConverter を明示的に JSON 以外出力されないように設定しておくほうが良いかもしれない * `Accept:application/xml` を利用していてそれに依存する利用者がいると困る、という程度だが…… # produces を指定した場合としない場合で実際どう挙動が変わるのか 以下のようなコントローラを実装する。 ```java @ResponseBody @GetMapping(value = "/json", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Map json() { return ImmutableMap.of("a", "b"); } @ResponseBody @GetMapping(value = "/musitei") public Map musitei() { return ImmutableMap.of("c", "d"); } ``` produces 指定がある場合、許可されていない Acccept ヘッダでリクエストすると `406 Not Acceptable` が返却される。 ``` $ curl -v http://localhost:8080/json * Trying ::1... * Connected to localhost (::1) port 8080 (#0) > GET /json HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Tue, 27 Sep 2016 21:47:24 GMT < Content-Type: application/json;charset=UTF-8 < Transfer-Encoding: chunked < * Connection #0 to host localhost left intact {"a":"b"} $ curl -v -H 'Accept: application/xml' http://localhost:8080/json * Trying ::1... * Connected to localhost (::1) port 8080 (#0) > GET /json HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.43.0 > Accept: application/xml > < HTTP/1.1 406 Not Acceptable < Date: Tue, 27 Sep 2016 21:47:02 GMT < Content-Type: application/xml;charset=UTF-8 < Transfer-Encoding: chunked < * Connection #0 to host localhost left intact 1475012826311406Not Acceptableorg.springframework.web.HttpMediaTypeNotAcceptableExceptionNot Acceptable/json ``` 無指定な場合、`Accept: application/xml` を指定すると、XML が返却される。 ``` $ curl -v http://localhost:8080/musitei * Trying ::1... * Connected to localhost (::1) port 8080 (#0) > GET /musitei HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Tue, 27 Sep 2016 21:48:51 GMT < Content-Type: application/json;charset=UTF-8 < Transfer-Encoding: chunked < * Connection #0 to host localhost left intact {"c":"d" $ curl -v -H 'Accept: application/xml' http://localhost:8080/musitei * Trying ::1... * Connected to localhost (::1) port 8080 (#0) > GET /musitei HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.43.0 > Accept: application/xml > < HTTP/1.1 200 OK < Date: Tue, 27 Sep 2016 21:48:30 GMT < Content-Type: application/xml;charset=UTF-8 < Transfer-Encoding: chunked < * Connection #0 to host localhost left intact d ``` # どのように判別されているのか 以下のあたりで、Accept ヘッダで許容可能と指定されている content-type とサーバーの設定で利用可能な HttpMessageConverter の突き合わせが行われ、利用可能ならシリアライザが使われる。 `org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters(T, org.springframework.core.MethodParameter, org.springframework.http.server.ServletServerHttpRequest, org.springframework.http.server.ServletServerHttpResponse)` とかにデバッグポイントしかけて見てみると、そのへんの挙動がわかる。 ```java HttpServletRequest request = inputMessage.getServletRequest(); List requestedMediaTypes = getAcceptableMediaTypes(request); List producibleMediaTypes = getProducibleMediaTypes(request, valueType, declaredType); if (outputValue != null && producibleMediaTypes.isEmpty()) { throw new IllegalArgumentException("No converter found for return value of type: " + valueType); } Set compatibleMediaTypes = new LinkedHashSet<>(); for (MediaType requestedType : requestedMediaTypes) { for (MediaType producibleType : producibleMediaTypes) { if (requestedType.isCompatibleWith(producibleType)) { compatibleMediaTypes.add(getMostSpecificMediaType(requestedType, producibleType)); } } } if (compatibleMediaTypes.isEmpty()) { if (outputValue != null) { throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes); } return; } ``` ## 利用可能な HttpMessageConverters はどこで決定されているのか `org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addDefaultHttpMessageConverters` です。 ```java protected final void addDefaultHttpMessageConverters(List> messageConverters) { StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(); stringConverter.setWriteAcceptCharset(false); messageConverters.add(new ByteArrayHttpMessageConverter()); messageConverters.add(stringConverter); messageConverters.add(new ResourceHttpMessageConverter()); messageConverters.add(new SourceHttpMessageConverter()); messageConverters.add(new AllEncompassingFormHttpMessageConverter()); if (romePresent) { messageConverters.add(new AtomFeedHttpMessageConverter()); messageConverters.add(new RssChannelHttpMessageConverter()); } if (jackson2XmlPresent) { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.xml().applicationContext(this.applicationContext).build(); messageConverters.add(new MappingJackson2XmlHttpMessageConverter(objectMapper)); } else if (jaxb2Present) { messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().applicationContext(this.applicationContext).build(); messageConverters.add(new MappingJackson2HttpMessageConverter(objectMapper)); } else if (gsonPresent) { messageConverters.add(new GsonHttpMessageConverter()); } } ``` AtomFeedHttpMessageConverter と RssChannelHttpMessageConverter については無視して良い。以下のように、特定のクラスのインスタンスの場合のみ動作するからだ。 ```java public class AtomFeedHttpMessageConverter extends AbstractWireFeedHttpMessageConverter { public AtomFeedHttpMessageConverter() { super(new MediaType("application", "atom+xml")); } @Override protected boolean supports(Class clazz) { return Feed.class.isAssignableFrom(clazz); } } ``` そういうわけで、問題は XML シリアライザが依存に入ってきたケースに挙動が変わるという点のみが問題となる。 # produces を指定すべきか そもそも produces を指定すべきかという点についてだが、atom, xml, rss 等を明示的に返却したい場合については指定したほうが良いかもしれない(別にしなくてもいい気もする)。 String などの raw type を JSON で返したい場合、StringHttpMessageConverter が優先されてしまうため明示的に指定しないといけない。 しかし大枠でいうと、JSON で返す API 全てに produces 属性を指定するとコードがゴチャゴチャするので HttpMessageConverter から除外する、などの対応を取ったほうがいいと思う。
Git::Database is yet another module I wrote to interact with Git. It wraps an OO-layer around Git objects (blobs, trees, commits, tags), in a way that's very similar to what Git::PurePerl does. It has no opinion on the actual means...
Here I am again making a summary of my work during the third trimester of my second year on the CPAN Pull Request Challenge: For July I got Algorithm-GooglePolylineEncoding. This module did not include a META.json file, so my PR...
I am pleased to announce that The Perl Foundation will be taking part in Outreachy again this year. We are offering one full-time internship in the winter program, which will run from December 6th to April 6th. The application process is now open and applications need to be submitted by October 17th. Our mentor, Dylan Hardison, from the Bugzilla project has provided a list of ideas and possible projects on our information page. Outreachy, formerly The Outreach Program for Women,...
Last updated: Fri Sep 30 13:13:21 2016