mozilla

Mozilla Nederland LogoDe Nederlandse
Mozilla-gemeenschap

Abonneren op feed Mozilla planet
Planet Mozilla - http://planet.mozilla.org/
Bijgewerkt: 4 uur 53 min geleden

About:Community: MDN Contributor of the Month for April 2015: Julien (Sphinx)

ma, 11/05/2015 - 11:02

As part of the recently launched recognition program for Mozilla Developer Network, I’m pleased to announce that our first Contributor of the Month, for April 2015, is Julien (a.k.a. Sphinx).

Julien (in the Batman t-shirt) with other Mozilla Francophone contributors at a localization sprint

Julien (in the Batman t-shirt) with other Mozilla Francophone contributors at a localization sprint

The MDN Contributor of the Month is selected from among those users who have been awarded an MDN Star badge for a “significant” contribution. Julien’s MDN Star badge was awarded for doing the “lion’s share” of effort to translate the entire JavaScript section of MDN into French. Many other contributors also helped in this effort, but Julien spent many nights and weekends over several months, translating JavaScript articles.

The following is a lightly-edited interview with Julien, conducted via email.

When and how did you get started contributing to MDN?

When? During Spring in 2013 when I was studying in Edinburgh, where I had some time for my personal projects.

How? I had already done a translation project with a French association called Framasoft (which closely related to Mozilla in terms of community here in France) and from one pad to another I ended up translating a small piece of article for mozilla-fr (mostly thanks to Goofy who was part of both projects). One thing leading to another, I discovered IRC, the nebula of Mozilla projects, and then MDN. After some edits, I discovered that the article about the <img> HTML tag was not available in French, so I localized it and that was it :)

How does what you do on MDN affect other parts of your life, or vice versa?

I’m not a developer but I have some background in IT and my job is about organizing projects with software, so I’d say it feels like two complementary part of what I want to learn and discover. With MDN, I can learn new things (like up-to-date JavaScript while localizing articles), see how an open project works, contribute to what I want, when I want. While at work, I can picture how this sometimes differs in companies where culture and methodologies are more classical. Both are really complementary in terms of skills, experience and knowledge.

Regarding the time I spend, I tend to contribute during evenings, almost every day (instead of watching TV ;) ) Of course, it doesn’t have to be every day! One should just find the rythm he/she is comfortable with and go with this.

And technically, MDN is affecting me with travels recently :) From Paris, to Berlin [for the Hack-on-MDN weekend] and Vancouver [for the Whistler work week], this is very exciting to meet people around MDN, whether they are employees or contributors and I’m very lucky to have these opportunities.

What advice do you have for new contributors on MDN?

Do hang out on IRC and ask questions [in the #mdn channel]. Do send an e-mail on the dev-mdc mailing list saying who you are and where you’d like to contribute. There are many people waiting to help you. If you prefer Twitter, go for it.

Contributing to MDN (and to Mozilla in general) can be a bit confusing at the beginning since there is a lot of stuff going on: don’t worry about that!

The MDN team is very helpful and looking forward to helping you :) See you soon on #mdn

If you don’t know where to start, you can contribute to the Learning Area or localize the glossary in your language or simply go to the Getting Started guide.

Categorieën: Mozilla-nl planet

Karl Dubost: How To Contact Web Sites For Web Compatibility Issues

ma, 11/05/2015 - 09:48

A lot of the content in this document has already been written in How to do sites outreach?. Let's go over it again. There is no way to ensure a methodology which is 100% effective. A lot come from practices, hunch and patience.

How To Behave?

When it's time to track down someone to help get the fix implemented, it is useful to keep in mind a few tips on doing outreach:

  • Be tactful: People we are trying to reach have their own set of constraints, bosses, economic choices, etc. "Your web site sucks" will not lead anywhere, except NOT getting the site fixed.
  • Be humble: We are no better, we also do mistakes in our own practices. We recommend things which might change one day because of the technical/economical circumstances.
  • Let it go: Sometimes it just doesn't work. The person at the end of the other line may say "no" or worse, not answer. It can be very frustrating. Accept it and move on.
  • Be passionate: The passion is in being able to find the right contact in a company without harassing them. Every effort helps.
  • Share with consideration Share any contact you attempted or made in the issue comments section. It helps everyone to know the status so they can pitch in or not repeat work. That said - be careful to not disclose private information such as names and emails if these contacts were not found publicly. You may simply say: "I contacted someone at $COMPANY", "Someone from $COMPANY said this..."
The Fabric Of Web Sites

There's not one way of making Web sites. Some Web sites are made in-house by a team of Developers hired by the company itself. Sometimes there are projects which are created by multiple Web agencies (marketing and development).

Scripts, images, design may come from different sources with their own source of bugs. A good analysis will provide a way to understand who you might want to reach out first. For example, a company Web site will use WordPress for the backend and a template from a third party company, the mistake is the template code. You will need then to get the template fixed and to have the company to update to the new version.

Some sites have no budget anymore to be updated. Some sites have very precise release cycles based on a yearly schedule, sometimes more. Understanding the structure of the web site may help in some circumstances.

Techniques For Finding Contacts Does the web site have a Twitter account?

If the Twitter account seems to be run by a person, it can be a good start for initial contact. A twitter account with a real person behind usually answers the questions of people, check the Tweet & Replies section. Ask who you should contact with the fix.

If the Twitter account is just broadcasting information, move on. You will lose time. Try to reach out through another mean.

Does the web site have a support email or an issue tracker?

This is a simple one, but there's no guarantee that your request will be addressed. Most of the time the responses are automatic but it's better than nothing. If in return you get an ID, reference number and/or a URI, put it in the issue comments. Sometimes bug reports are closed without notice. It really depends on who is behind the triage of the bug reporting system.

Who/What is creating the web site?

Going through digital marketing Web site and magazine might help in finding who (person) or what (Web marketing agency) created the Web site. While the person in charge of changing the site is at the company, the people who will be doing the work might be from an external agency. Finding out the agency might help you channel the information upstream to the company, if there are still in good terms.

Search for a human

It's wonderful when you can find the right person right away. But more often it's not the case. So the goal here is about finding someone who will be kind enough to lead you to the right person. Human networks are often more effective than the company process for dealing with customer issues.

Some professions are more public than others. Some developers exposed themselves more than others. For example, developers such as Front-End developers, Web Designers, are easier to contact than backend or DB developers.

Linkedin

This doesn't necessary work with all countries, but worth trying. For example, in Japan and China it's a lot more difficult to find a contact through linkedin. You can start for example in your favorite search engine with: 'Web developer' $COMPANY_NAME site:linkedin.com. This will list names of people who are likely to work there, some of them in their profile will have contact information and often Twitter accounts, personal web sites or emails. Their linkedin username might be very similar to their username on other social networks.

Once you reached a profile page, in the right column, you may found other people working at the same company. You will also notice that often people who puts their photos on the linkedin profile are often more reachable.

'Web Developer' might not always be the right string to search. Depending on the countries, people will label themselves differently such as 'Web Engineer' or 'Software Developer'.

Twitter

Some people put their company affiliation in Twitter. Tweet or DM them if possible and ask who to contact. Always check if the Twitter account is active. Some people haven't used their account for ages. If so, move on.

Slideshare

When you can't find the information about a developer, you might want to try to search something such as $COMPANY_NAME site:slideshare.net or any appropriate keywords that will make you closer to a contact. Some companies have their developers speaking at conferences about issues with performances, etc. Be careful of talks related to sales or marketing. In the slides, there is often the contact information of the developer.

Github

Search by individual person or by company names. Many developers have either company projects online and/or their personal projects. As usual be careful to not abuse or harass people with your requests.

When you find a company repository, check the most recent project, and you might find who are the recent committers on the code. These are the ones who are the most recently active and likely to respond to your request. The backend of Webcompat.com is provided by GitHub so you may want to comment with @username syntax to reach out a specific developer.

Web designer

Sometimes when you can't reach a web developer, you may try to reach web designers who have also their own type of social networks such as dribbble.com. Usually they have contacts with web developers and may be able to give an introduction. In some web agencies, the web designer will be a good initial contact. Again, be tactful and don't make the life of the web designer harder in his/her own company.

Corporate emails

This may work time to time. When you know the person is working in a specific company (You have last and first name), but you have been unable to find any contacts at all through twitter and so on. You might want to find out through search engines and/or people working at this company how the email addresses have been created. You may find that the pattern is firstname.lastname@company.example.org or lastnameF@, etc. You can try to send an email.

The person will be probably surprised on how did you get the email address. So there is a risk to anger the person. Be gentle and just explain how you found the person.

Try this email format tool.

  • whois. Some Web sites have their contact information in the whois of the Web site. It's becoming rarer and rarer, because people receive spam because of it.
  • Check the terms and conditions or privacy policy for email addresses. There could be hidden in long blocks of text so a search for @ is helpful. There may also be links in a website's footer to an investor or media relations page which could have a contact address, but be careful not to annoy the company by sending mails about bugs to addresses that are clearly not relevant (e.g. investors@example.com).
  • Friend of a friend. You are likely well connected in the industry. And it's why, if you are a Mozilla contributor in a specific country, you are a very important asset for the work we are doing. Local social networks in between companies is a lot denser. Search your LinkedIn, Twitter and Github for connections who might be connected to that company.
  • Find the home site. Sometimes a Web site belongs to a bigger company (think about a Game company with many brands, or a TV broadcaster, different services such as Google, Yahoo!, etc.), finding the home site will help understand the structure of the company and might lead to the department which is really in charge of the Web site.
  • Check for unique technologies that can search for. Sometimes you may have additional hints about the technology used on the Web site and the type of people related to the site through the hiring page of the company. In small company Web sites, you will discover the programming languages which are used, these will help reduce the search.
Patience

All of these techniques are not 100% perfect. They might fail more often than you wish. Sometimes you need to try multiple times and develop new techniques for finding the right person.

If you have any other tips, recommendations on how to contact the right person, please come on IRC and tell us on freenode #webcompat and/or irc.mozilla.org #webcompat.

Otsukare!

Categorieën: Mozilla-nl planet

Andy McKay: Stricter API filtering

ma, 11/05/2015 - 09:00

Django Rest Framework and Tastypie both provide REST queries and allow looking up lists of objects based on query parameters. In the former case it allows multiple back-ends, but defaults to using Django filter.

That's a fine approach with one problem. Consider this:

http://example.com/api/products?category=clothing

You've got a reasonably good idea of what that will return. How about this one?

http://example.com/api/products?categry=clothing

What does that return? Everything. Because category got typo'd. Meaning that it was excluded from the filter and you didn't filter on anything at all. Ouch.

Out of the box Django Rest Framework only allows GETs on lists. Even a GET that goes awry like that is bad. But you can use the bulk library to do PATCH, PUT and DELETE.

DELETE http://example.com/api/products?categry=clothing

That's really going to ruin your day. Kumar rightly complained about this so I threw in a simple filter to stop that.

from rest_framework.exceptions import ParseError from rest_framework.filters import DjangoFilterBackend class StrictQueryFilter(DjangoFilterBackend): def filter_queryset(self, request, queryset, view): requested = set(request.QUERY_PARAMS.keys()) allowed = set(getattr(view, 'filter_fields', [])) difference = requested.difference(allowed) if difference: raise ParseError( detail='Incorrect query parameters: ' + ','.join(difference)) return (super(self.__class__, self) .filter_queryset(request, queryset, view))

Once it's done alter: DEFAULT_FILTER_BACKENDS to point to that and make sure your filter_fields are correct.

Now a typo'd query string will return you a 422 error.

Categorieën: Mozilla-nl planet

Andy McKay: Moving to GitHub issues

ma, 11/05/2015 - 09:00

Mozilla wasn't my first time using Bugzilla. About ten years earlier I worked at ActiveState and spent hours hacking away at Bugzilla with a certain David Ascher to produce an issue tracker for the company.

That was forever ago, when I was a junior who knew nothing and found Bugzilla a bit of a mess. But that was ages ago, software improves and life moves on.

We've used Bugzilla every day at Mozilla for Add-ons and the Marketplace. Actually came to like Bugzilla, sort of. But recently we had an opportunity to move onto a new project - and we decided to move issues to GitHub.

Again I'm going to blame David Ascher who one day asked me "Have you tried putting your issues on GitHub?". I gave a list of reasons why not. Then later on I realised they were mostly bogus and the only real reason had become "Because that's what we've always done."

The biggest reason I could think of is that GitHub is repository based. As an example... suppose there's a bug in Payments, where do I file an issue? The payments-server, the payments-ui, the payments-example repository? It's not project based. So we created a payments repository that's a catch all for issues and documentation. Problem solved.

By moving to GitHub issues we've gained:

  • faster performance
  • better integration with our code and pull requests
  • ability to link-in other tools (e.g. http://waffle.io)
  • lose a whole pile of features, settings and flags we never use
  • lose getting told off for features that cross products, e.g. the time people removed [perf] off our bugs because that reserved for something in Firefox

So far the things we've lost are:

  • ability to file security or Mozilla confidential bugs, but for that we just use Bugzilla

But so far everything is great.

My favourite thing is using waffle.io which provides us with a Kanban flow across multiple repos and is pretty awesome.

I tried to use a similar tool with Bugzilla that an intern wrote. But surprise, the tool wasn't maintained, didn't always worked and I ended up maintaining it. I didn't want to do that, I just want good tools that other people maintain so I can ship my project.

Oh the last downside? When GitHub goes down:

If you are still reading this blog post, I strongly encourage you not to think about ditching Bugzilla, but to think about your entire tool chain set and find new tools and improvements when you can. Oh, and read Gregory Szorc's blog.

Categorieën: Mozilla-nl planet

Mike Taylor: CircleKSunkus and CSS Zoom

ma, 11/05/2015 - 07:00

In this, the Nth installation of the Weird World Wide Web Websites series we take a look at circleksunkus.jp, purveyor of fine Japanese soft drinks and snacks.

If you load this site on a Firefox mobile browser you might think you're up against some old -webkit- prefixed flexbox code. Or maybe one of those fun edgecase float differences between WebKit and Gecko.

screenshot of circlesunkus.jp website

But nope, it's even weirder.

//viewport $(window).bind('resize load', function(){ $("html").css("zoom" , $(window).width()/640 ); });

They're using IE's olde non-standard CSS zoom property (that WebKit implemented back in the Safari 4 days) to retrigger a zoomed out layout on page load, which leads to a pretty harsh Flash of Un-Zoomed-Out Content (FOUZOC) if you're on a third world internet connection (like the ones we have here in Texas).

Anyways, if you happen to work on circlesunkus.jp, here's how to do this the right way™:

<meta name="viewport" content="width=640">

More info in the webcompat bug.

Categorieën: Mozilla-nl planet

The Rust Programming Language Blog: Abstraction without overhead: traits in Rust

ma, 11/05/2015 - 02:00

Previous posts have covered two pillars of Rust’s design:

  • Memory safety without garbage collection
  • Concurrency without data races

This post begins exploring the third pillar:

  • Abstraction without overhead

One of the mantras of C++, one of the qualities that make it a good fit for systems programming, is its principle of zero-cost abstraction:

C++ implementations obey the zero-overhead principle: What you don’t use, you don’t pay for [Stroustrup, 1994]. And further: What you do use, you couldn’t hand code any better.

– Stroustrup

This mantra did not always apply to Rust, which for example used to have mandatory garbage collection. But over time Rust’s ambitions have gotten ever lower-level, and zero-cost abstraction is now a core principle.

The cornerstone of abstraction in Rust is traits:

  • Traits are Rust’s sole notion of interface. A trait can be implemented by multiple types, and in fact new traits can provide implementations for existing types. On the flip side, when you want to abstract over an unknown type, traits are how you specify the few concrete things you need to know about that type.

  • Traits can be statically dispatched. Like C++ templates, you can have the compiler generate a separate copy of an abstraction for each way it is instantiated. This comes back to the C++ mantra of “What you do use, you couldn’t hand code any better” – the abstraction ends up completely erased.

  • Traits can be dynamically dispatched. Sometimes you really do need an indirection, and so it doesn’t make sense to “erase” an abstraction at runtime. The same notion of interface – the trait – can also be used when you want to dispatch at runtime.

  • Traits solve a variety of additional problems beyond simple abstraction. They are used as “markers” for types, like the Send marker described in a previous post. They can be used to define “extension methods” – that is, to add methods to an externally-defined type. They largely obviate the need for traditional method overloading. And they provide a simple scheme for operator overloading.

All told, the trait system is the secret sauce that gives Rust the ergonomic, expressive feel of high-level languages while retaining low-level control over code execution and data representation.

This post will walk through each of the above points at a high level, to give you a sense for how the design achieves these goals, without getting too bogged down in the details.

Background: methods in Rust

Before delving into traits, we need to look at a small but important detail of the language: the difference between methods and functions.

Rust offers both methods and free-standing functions, which are very closely related:

struct Point { x: f64, y: f64, } // a free-standing function that converts a (borrowed) point to a string fn point_to_string(point: &Point) -> String { ... } // an "inherent impl" block defines the methods available directly on a type impl Point { // this method is available on any Point, and automatically borrows the // Point value fn to_string(&self) -> String { ... } }

Methods like to_string above are called “inherent” methods, because they:

  • Are tied to a single concrete “self” type (specified via the impl block header).
  • Are automatically available on any value of that type – that is, unlike functions, inherent methods are always “in scope”.

The first parameter for a method is always an explicit “self”, which is either self, &mut self, or &self depending on the level of ownership required. Methods are invoked using the . notation familiar from object-oriented programming, and the self parameter is implicitly borrowed as per the form of self used in the method:

let p = Point { x: 1.2, y: -3.7 }; let s1 = point_to_string(&p); // calling a free function, explicit borrow let s2 = p.to_string(); // calling a method, implicit borrow as &p

Methods and their auto-borrowing are an important aspect of the ergonomics of Rust, supporting “fluent” APIs like the one for spawning processes:

let child = Command::new("/bin/cat") .arg("rusty-ideas.txt") .current_dir("/Users/aturon") .stdout(Stdio::piped()) .spawn(); Traits are interfaces

Interfaces specify the expectations that one piece of code has on another, allowing each to be switched out independently. For traits, this specification largely revolves around methods.

Take, for example, the following simple trait for hashing:

trait Hash { fn hash(&self) -> u64; }

In order to implement this trait for a given type, you must provide a hash method with matching signature:

impl Hash for bool { fn hash(&self) -> u64 { if *self { 0 } else { 1 } } } impl Hash for i64 { fn hash(&self) -> u64 { *self as u64 } }

Unlike interfaces in languages like Java, C# or Scala, new traits can be implemented for existing types (as with Hash above). That means abstractions can be created after-the-fact, and applied to existing libraries.

Unlike inherent methods, trait methods are in scope only when their trait is. But assuming Hash is in scope, you can write true.hash(), so implementing a trait extends the set of methods available on a type.

And… that’s it! Defining and implementing a trait is really nothing more than abstracting out a common interface satisfied by more than one type.

Static dispatch

Things get more interesting on the other side – consuming a trait. The most common way of doing so is through generics:

fn print_hash<T: Hash>(t: &T) { println!("The hash is {}", t.hash()) }

The print_hash function is generic over an unknown type T, but requires that T implements the Hash trait. That means we can use it with bool and i64 values:

print_hash(&true); // instantiates T = bool print_hash(&12_i64); // instantiates T = i64

Generics are compiled away, resulting in static dispatch. That is, as with C++ templates, the compiler will generate two copies of the print_hash method to handle the above code, one for each concrete argument type. That in turn means that the internal call to t.hash() – the point where the abstraction is actually used – has zero cost: it will be compiled to a direct, static call to the relevant implementation:

// The compiled code: __print_hash_bool(&true); // invoke specialized bool version directly __print_hash_i64(&12_i64); // invoke specialized i64 version directly

This compilation model isn’t so useful for a function like print_hash, but it’s very useful for more realistic uses of hashing. Suppose we also introduce a trait for equality comparison:

trait Eq { fn eq(&self, other: &Self) -> bool; }

(The reference to Self here will resolve to whatever type we implement the trait for; in impl Eq for bool it will refer to bool.)

We can then define a hash map that is generic over a type T implementing both Hash and Eq:

struct HashMap<Key: Hash + Eq, Value> { ... }

The static compilation model for generics will then yield several benefits:

  • Each use of HashMap with concrete Key and Value types will result in a different concrete HashMap type, which means that HashMap can lay out the keys and values in-line (without indirection) in its buckets. This saves on space and indirections, and improves cache locality.

  • Each method on HashMap will likewise generate specialized code. That means there is no extra cost dispatching to calls to hash and eq, as above. It also means that the optimizer gets to work with the fully concrete code – that is, from the point of view of the optimizer, there is no abstraction. In particular, static dispatch allows for inlining across uses of generics.

Altogether, just as in C++ templates, these aspects of generics mean that you can write quite high-level abstractions that are guaranteed to compile down to fully concrete code that “you couldn’t hand code any better”.

But, unlike with C++ templates, clients of traits are fully type-checked in advance. That is, when you compile HashMap in isolation, its code is checked once for type correctness against the abstract Hash and Eq traits, rather than being checked repeatedly when applied to concrete types. That means earlier, clearer compilation errors for library authors, and less typechecking overhead (i.e., faster compilation) for clients.

Dynamic dispatch

We’ve seen one compilation model for traits, where all abstraction is compiled away statically. But sometimes abstraction isn’t just about reuse or modularity – sometimes abstraction plays an essential role at runtime that can’t be compiled away.

For example, GUI frameworks often involve callbacks for responding to events, such as mouse clicks:

trait ClickCallback { fn on_click(&self, x: i64, y: i64); }

It’s also common for GUI elements to allow multiple callbacks to be registered for a single event. With generics, you might imagine writing:

struct Button<T: ClickCallback> { listeners: Vec<T>, ... }

but the problem is immediately apparent: that would mean that each button is specialized to precisely one implementor of ClickCallback, and that the type of the button reflects that type. That’s not at all what we wanted! Instead, we’d like a single Button type with a set of heterogeneous listeners, each potentially a different concrete type, but each one implementing ClickCallback.

One immediate difficulty here is that, if we’re talking about a heterogeneous group of types, each one will have a distinct size – so how can we even lay out the internal vector? The answer is the usual one: indirection. We’ll store pointers to callbacks in the vector:

struct Button { listeners: Vec<Box<ClickCallback>>, ... }

Here, we are using the ClickCallback trait as if it were a type. Actually, in Rust, traits are types, but they are “unsized”, which roughly means that they are only allowed to show up behind a pointer like Box (which points onto the heap) or & (which can point anywhere).

In Rust, a type like &ClickCallback or Box<ClickCallback> is called a “trait object”, and includes a pointer to an instance of a type T implementing ClickCallback, and a vtable: a pointer to T’s implementation of each method in the trait (here, just on_click). That information is enough to dispatch calls to methods correctly at runtime, and to ensure uniform representation for all T. So Button is compiled just once, and the abstraction lives on at runtime.

Static and dynamic dispatch are complementary tools, each appropriate for different scenarios. Rust’s traits provide a single, simple notion of interface that can be used in both styles, with minimal, predictable costs. Trait objects satisfy Stroustrup’s “pay as you go” principle: you have vtables when you need them, but the same trait can be compiled away statically when you don’t.

The many uses of traits

We’ve seen a lot of the mechanics and basic use of traits above, but they also wind up playing a few other important roles in Rust. Here’s a taste:

  • Closures. Somewhat like the ClickCallback trait, closures in Rust are simply particular traits. You can read more about how this works in Huon Wilson’s in-depth post on the topic.

  • Conditional APIs. Generics make it possible to implement a trait conditionally:

struct Pair<A, B> { first: A, second: B } impl<A: Hash, B: Hash> Hash for Pair<A, B> { fn hash(&self) -> u64 { self.first.hash() ^ self.second.hash() } }

Here, the Pair type implements Hash if, and only if, its components do – allowing the single Pair type to be used in different contexts, while supporting the largest API available for each context. It’s such a common pattern in Rust that there is built-in support for generating certain kinds of “mechanical” implementations automatically:

#[derive(Hash)] struct Pair<A, B> { .. }
  • Extension methods. Traits can be used to extend an existing type (defined elsewhere) with new methods, for convenience, similarly to C#’s extension methods. This falls directly out of the scoping rules for traits: you just define the new methods in a trait, provide an implementation for the type in question, and voila, the method is available.

  • Markers. Rust has a handful of “markers” that classify types: Send, Sync, Copy, Sized. These markers are just traits with empty bodies, which can then be used in both generics and trait objects. Markers can be defined in libraries, and they automatically provide #[derive]-style implementations: if all of a types components are Send, for example, so is the type. As we saw before, these markers can be very powerful: the Send marker is how Rust guarantees thread safety.

  • Overloading. Rust does not support traditional overloading where the same method is defined with multiple signatures. But traits provide much of the benefit of overloading: if a method is defined generically over a trait, it can be called with any type implementing that trait. Compared to traditional overloading, this has two advantages. First, it means the overloading is less ad hoc: once you understand a trait, you immediately understand the overloading pattern of any APIs using it. Second, it is extensible: you can effectively provide new overloads downstream from a method by providing new trait implementations.

  • Operators. Rust allows you to overload operators like + on your own types. Each of the operators is defined by a corresponding standard library trait, and any type implementing the trait automatically provides the operator as well.

The point: despite their seeming simplicity, traits are a unifying concept that supports a wide range of use cases and patterns, without having to pile on additional language features.

The future

One of the primary ways that languages tend to evolve is in their abstraction facilities, and Rust is no exception: many of our post-1.0 priorities are extensions of the trait system in one direction or another. Here are some highlights.

  • Statically dispatched outputs. Right now, it’s possible for functions to use generics for their parameters, but there’s no equivalent for their results: you cannot say “this function returns a value of some type that implements the Iterator trait” and have that abstraction compiled away. This is particularly problematic when you want to return a closure that you’d like to be statically-dispatched – you simply can’t, in today’s Rust. We want to make this possible, and have some ideas already.

  • Specialization. Rust does not allow overlap between trait implementations, so there is never ambiguity about which code to run. On the other hand, there are some cases where you can give a “blanket” implementation for a wide range of types, but would then like to provide a more specialized implementation for a few cases, often for performance reasons. We hope to propose a design in the near future.

  • Higher-kinded types (HKT). Traits today can only be applied to types, not type constructors – that is, to things like Vec<u8>, not to Vec itself. This limitation makes it difficult to provide a good set of container traits, which are therefore not included in the current standard library. HKT is a major, cross-cutting feature that will represent a big step forward in Rust’s abstraction capabilities.

  • Efficient re-use. Finally, while traits provide some mechanisms for reusing code (which we didn’t cover above), there are still some patterns of reuse that don’t fit well into the language today – notably, object-oriented hierarchies found in things like the DOM, GUI frameworks, and many games. Accommodating these use cases without adding too much overlap or complexity is a very interesting design problem, and one that Niko Matsakis has started a separate blog series about. It’s not yet clear whether this can all be done with traits, or whether some other ingredients are needed.

Of course, we’re at the eve of the 1.0 release, and it will take some time for the dust to settle, and for the community to have enough experience to start landing these extensions. But that makes it an exciting time to get involved: from influencing the design at this early stage, to working on implementation, to trying out different use cases in your own code – we’d love to have your help!

Categorieën: Mozilla-nl planet

Joel Maher: intermittent oranges- missing a real definition

zo, 10/05/2015 - 23:49

There are all kinds of great ideas folks have for fixing intermittent issues.  In fact each idea in and of itself is a worthwhile endeavor.   I have spent some time over the last couple of months fixing them, filing bugs on them, and really discussing them.  One question that remains- what is the definition of an intermittent.

I don’t plan to lay out a definition, instead I plan to ask some questions and lay out some parameters.  According to orange factor, there are 4640 failures in the last week (May 3 -> May 10) all within 514 unique bugs.  These are all failures that the sheriffs have done some kind of manual work on to star on treeherder.  I am not sure anybody can find a way to paint a pretty picture to make it appear we don’t have intermittent failures.

Looking at a few bugs, there are many reasons for intermittent failures:

  • core infrastructure (networking, power, large classes of machines (ec2), etc.)
  • machine specific (specific machine is failing a lot of jobs)
  • CI specific (buildbot issues, twisted issues, puppet issues, etc.)
  • CI Harness (usually mozharness)
  • Platforms (old platforms/tests we are phasing out, new platforms/tests we are phasing in)
  • Test harness (mochitest + libraries, common code for tests, reftest)
  • Test Cases (test cases actually causing failures, poorly written, new test cases, etc.)
  • Firefox Code (we actually have introduced conditions to cause real failures- just not every time)
  • Real regressions (failures which happen every time we run a test)

There are a lot of reasons, many of these have nothing to do with poor test cases or bad code in Firefox.  But many of these are showing up many times a day and as a developer who wants to fix a bad test, many are not really actionable.  Do we need to have some part of a definition to include something that is actionable?

Looking at the history of ‘intermittent-failure’ bugs in Bugzilla, many occur once and never occur again.  In fact this is the case for over half of the bugs filed (we file upwards of 100 new bugs/week).  While there are probably reasons for a given test case to fail, if it failed in August 2014 and has never failed again, is that test case intermittent?  As a developer could you really do anything about this given the fact that reproducing it is virtually impossible?

This is where I start to realize we need to find a way to identify real intermittent bugs/tests and not clutter the statistics with tests which are virtually impossible to reproduce.  Thinking back to what is actionable- I have found that while filing bugs for Talos regressions the closer the bug is filed to the original patch landing, the better the chance it will get fixed.  Adding to that point, we only keep 30 days of builds/test packages around for our CI automation.  I really think a definition of an intermittent needs to have some kind of concept of time.  Should we ignore intermittent failures which occur only once in 90 days?  Maybe ignore ones that don’t reproduce after 1000 iterations?  Some could argue that we look in a smaller or larger window of time/iterations.

Lastly, when looking into specific bugs, I find many times they are already fixed.  Many of the intermittent failures are actually fixed!  Do we track how many get fixed?  How many have patches and have debugging already taking place?  For example in the last 28 days, we have filed 417 intermittents, of which 55 are already resolved and of the remaining 362 only 25 have occurred >=20 times.  Of these 25 bugs, 4 already have patches.  It appears a lot of work is done to fix intermittent failures which are actionable.  Are the ones which are not being fixed not actionable?  Are they in a component where all the developers are busy and heads down?

In a perfect world a failure would never occur, all tests would be green, and all users would use Firefox.  In reality we have to deal with thousands of failures every week, most of which never happen again.  This quarter I would like to see many folks get involved in discussions and determine:

  • what is too infrequent to be intermittent? we can call this noise
  • what is the general threshold where something is intermittent?
  • what is the general threshold where we are too intermittent and need to backout a fix or disable a test?
  • what is a reasonable timeframe to track these failures such that we can make them actionable?

Thanks for reading, I look forward to hearing from many who have ideas on this subject.  Stay tuned for an upcoming blog post about re-trigging intermittent failures to find the root cause.


Categorieën: Mozilla-nl planet

Mike Conley: Things I’ve Learned This Week (May 4 – May 8, 2015)

zo, 10/05/2015 - 22:00
How to convert an NSString to a Gecko nsAString

I actually discovered this during my most recent Joy of Coding episode – there is a static utility method to convert between native Cocoa NSStrings and Gecko nsAStrings – nsCocoaUtils::GetStringForNSString. Very handy, and works exactly as advertised.

An “Attach to Process by pid” Keyboard Shortcut for XCode

I actually have colleague Garvan Keeley to thank for this one, and technically I learned this on April 24th. It was only this week that I remembered I had learned it!

When I’m debugging Firefox on OS X, I tend to use XCode, and I usually attach to Firefox after it has started running. I have to navigate some menus in order to bring up the dialog to attach to a process by pid, and I was getting tired of doing that over and over again.

So, as usual, I tweeted my frustration:

Dear lazyweb – is there an XCode keyboard shortcut for “Attach to Process” > “By Process Identifier (PID) or Name”? Mousing it blows.

— Mike Conley (@mike_conley) April 24, 2015

AND LO, THE INTERNET SPOKE BACK:

@mike_conley Yes. Shift-cmd-/, type ‘attach’, down arrow, enter, type proc name. next time, ‘attach’ and proc name is remembered. — Garvan Keeley (@garvankeeley) April 24, 2015

It seems small, but the savings in time for something that I do so frequently quickly adds up. And it always feels good to go faster!

Categorieën: Mozilla-nl planet

Andy McKay: Catching unused Python mocks

zo, 10/05/2015 - 09:00

It's easy for mocks to get out of hand and I've seen tests that have many mocks and patches. That in itself is bad enough, but I want to make sure that each mock is there for a reason. Over time tests get been copy and pasted or underlying code has changes - meaning mocks exist but are no longer used.

You can do this my asserting that each mock is called in the test. I've seen tests with that end up being 4 lines of mocks, a call, then 4 lines of checking the mocks are being called. Clearly, something was going wrong with those tests in the first place.

Anyway, I wanted to keep my tests clean in the future, so I added a registration step for mocks. Here's a simplified version:

def setUp(self): self.mocks = {} for name, obj in self.registered_mocks.items(): self.mocks[name] = OurMock(name, spec=obj) self.addCleanup(self.cleanUpMocks)

OurMock is a special mock that registers all the mocks registered against it. This pattern is pretty specific to the type of object I'm mocking in the tests:

class OurMock(mock.Mock): def __getattr__(self, name): if not name.startswith('_'): setattr(self, '_registered', []) self._registered.append(name) return super(OurMock, self).__getattr__(name)

Then on cleanUp:

def cleanUpMocks(self): for k, v in self.mocks.items(): for call in getattr(v, '_registered', []): if not getattr(v, call).called: raise MockError('{0}.{1} registered but not called.' .format(self.registered_mocks[k].__name__, call))

So a test now reads:

class Test(tests.TestCase): self.registered_mocks = {'some': object} def test_ok(self): self.mocks['some'].create.return_value = something()

In this example: create is in the list of _registered on the Mock. When the test completes we check it got called. If you run that test without anything else, it will fail because the mock never actually got called.

If what is passed to the mock is important, all the usual methods like assertcalledwith can be called.

This has already caught a few errors in my tests.

Categorieën: Mozilla-nl planet

Raniere Silva: MathML Accessibility

zo, 10/05/2015 - 05:00
MathML Accessibility

Frédéric Wang wrote a nice post about MathML Accessibility that has a comparison table between NVDA, VoiceOver and Orca.

I promised to Frédéric to provide a sample of the support of Firefox OS’ screen reader and you can find it here (it is a ogg file with the video in theora and the audio in vorbis).

Note

For the test I used this app.

Leia mais...

Categorieën: Mozilla-nl planet

Cameron Kaiser: 31.7.0 available

zo, 10/05/2015 - 02:46
31.7.0 is now available for testing (release notes, downloads, hashes). Although there is no new functionality or Power Mac-specific changes in this release, builders will notice some moderate churn in the changesets due to Mozilla invalidating about a third of them with a purely stylistic change to JavaScript code, making this release somewhat more troublesome than it had to be. (I don't know why they bothered doing that with a branch they plan to sunset in only about two more release cycles, but I digress.) It will finalize on Monday evening Pacific time as usual.

38 is on time for a beta release in a few weeks, though I need to do some more prophylactic changes to its changesets as well for the same reason. Once the 38 beta gets off the ground, then we will begin the final exodus from Google Code.

Categorieën: Mozilla-nl planet

Andy McKay: Preventing typos with Python mock

za, 09/05/2015 - 09:00

Python mock is pretty cool, but there's been a recurring problem for me with mock in that if you access any property on a Mock it returns a method which is truthy. This means simple typos can exist in your testing.

As an example, in this library, there's a method from_nonce. If you just mock the object, then you can typo the method and it continues like normal:

>>> with mock.patch('braintree.CreditCard') as mocked: ... assert mocked.from_none ...

This has happened to me and I didn't notice when I'd typo'd a mock call, like is_called. The test were wrong, but passed quite happily.

The better way is to pass the object to the Mock call as spec. Then only methods on the object can be called, for example:

>>> with mock.patch('braintree.CreditCard', spec=braintree.CreditCard) as mocked: ... assert mocked.from_none ... Traceback (most recent call last): [..snip] File "/Users/andy/.virtualenvs/solitude/lib/python2.7/site-packages/mock.py", line 658, in __getattr__ raise AttributeError("Mock object has no attribute %r" % name) AttributeError: Mock object has no attribute 'from_none'

Much better.

Categorieën: Mozilla-nl planet

Pagina's