> может стоит ипользовать плагин acct_as_tree ??
Именно он раньше и использовался, но там нельзя сделать множество родительских узлов...
> поможет has_and_belongs_to_many или has_many :through
Это понятно, но это подходит для связывания двух разных таблиц отношением N:M, а мне надо для одной таблицы...
So you found yourself in the need to override a method but still count on it’s old behaviour?
No problem! Override it with your new code, call super and…. Uh oh!! Suddenly this turned into a problem… Let me give some more context.
I was testing Ferret (and the acts_as_ferret plugin) in a project to provide full [...]
Je suis assez nouveau sur RoR, alors si ma question vous paraît hallucinante, remettez-la dans son contexte ...
Note préliminaire : je développe depuis 15 ans, et je trouve Ruby et RoR franchement intéressants !
Mon problème : lors de la génération des "scaffold", on obtient entre autres des pages au format ".html.erb" toutes faites (c'est le but). Il n'y a aucun effort de la part du générateur concernant la présentation dans les pages générées, ce qui me paraît tout à fait normal.
Ma question : comment faire en sorte que les pages générées soient plus en rapport avec le look général de mon application ? Actuellement, je suis obligé de ré-écrire quasiment intégralement les pages générées pour qu'elles ait un aspect acceptable du point de vue utilisateur (quand je dis ré-écrire, je veux dire : modifier de très nombreuses lignes - une majorité, en fait -).
Congrats to Vixmio for its recent write up in Forbes.
“For Web publishers, Viximo offers a soup-to-nuts virtual gifting service that provides digital content from its community of independent developers, billing via Paypal, a revenue-share program with artists and their sites, and analytical tools that track what goods sell well. The aim, says Frasca, is to [...]
A week ago Jumana (our administrative assistant at Akhtaboot) transferred a phone call for me. This call was from a guy who speaks English and I wasn’t able to hear his voice clearly. But I figured out that he needs a sponsorship from Akhtaboot. I’m not going to tell you the whole story but at [...]
On the 23rd of July 08, facebook held their annual showcase with the developer community. In the past its often been used to make major announcements that affected the platform. This year’s event was held at the San Francisco Design Center 635 8th Street, San Francisco, CA 94301. Below is a summary.
May be you guys have noticed that when you try to install a new gem on your machine it says some thing like “Updating meta data for 500 gems” and display one dot per gem. These dots moves very slowly and stops in some time.
I faced this situation many times and found a solution [...]
I have been asked more than once by friends and associates about what applications I use or recommend for OSX. I am sure this is not an uncommon occurrence for folks who enjoy sharing the positive experiences they have had on the Apple platform. This morning I remembered a site I came across many months ago that allows people to track the applications they use (and I believe it also notifies
After nearly two years of Rails development it’s more than time that I released my first (official) plugin. So here it goes.
If you’ve watched Rails on Lighthouse and GitHub lately, you’ve probably noticed that I’ve proposed quite a number of patches, especially regarding the new Rails i18n plugin (which by the way got me the 2nd place in the July 2008 Rails Hackfest – congrats to Tarmo Tnav at this point).
However, the date and time API got only partial i18n/l10n coverage – date and time formatting wasn’t included – which is where my new plugin, localized_dates, might come in handy.
The quickest way to get going is to simply install the plugin from its GitHub repository:
As part of its installation, this will copy two locale files (en-US.rb and de-AT.rb) to your config/locales folder. en-US is basically there to keep the current functionality and date definitions in place. de-AT serves as a demo on how you can write your own locale.
Opera published the Web Standards Curriculum, a series of articles which were released in association with the Yahoo! Developer Network, the goal is to:
teach you standards-based web development, including HTML, CSS, design principles and background theory, and JavaScript basics.
I find the initiative very positive, there’s already 23 articles and 30 more are coming until the end of [...]
На любой rake консоль выдает это:
C:\lovdbyless>rake lovdbyless:getting_started
(in C:/lovdbyless)
rake aborted!
undefined method `remove_task' for #<rake::application:0x2cdebd0>
C:/lovdbyless/rakefile:10
(See full trace by running task with --trace)
C:\lovdbyless>rake
(in C:/lovdbyless)
rake aborted!
undefined method `remove_task' for #<rake::application:0x2ce04d0>
C:/lovdbyless/rakefile:10
(See full trace by running task with --trace)
Architecture, for me anyway, involves intention, game theory, systems thinking and relentless testing and improvement. Fine with me if you want to call it design, just don't forget to do it. (via)
Есть ли стандартные методы для реализации субжа? Т.е. я например создал форму, и в ней input или textarea, и хочу чтобы было ограничение в этим полях на максимальный ввод символов (скажем, 100).
Some time ago, perhaps inspired by the daily comics-watching antics of The Comics Curmudgeon and Garfield Minus Garfield, I started a new comics-oriented blog. The premise of this blog is simple: Most of these so-called "comics" or "funnies" are anything but funny; Many of them can be enhanced (I'll stop short of saying "improved" or "made funnier") by replacing the last text bubble with a single stupid punchline. The results can be humorous, absurd, ribald, or scatological. See for yourself at Comics In My Pants. I've kept it going for a month now, dredging through the daily strips looking for spots where my punchline of choice seems to fit, at least syntactically. Enjoy!
Je n’ai pas parlé de la version 0.2 le mois dernier, mais voici la version 0.2.1 qui marque l’arrivée d’un package permettant de développer son application sans avoir à installer quoi que ce soit (à part Java).
Je l’ai nommé Qt::JRuby Complete. Il suffit de le télécharger, le décompresser et d’éditer le fichier main.rb qui contient déjà une petite application. Ensuite pour lancer l’application, il suffit de taper la commande suivante :
java -jar ./jars/qtjruby-0.2.1.jar main.rb
L’archive est un peu lourde puisqu’il y a beaucoup de composants à l’intérieur (JRuby Complete + Qt Jambi pour Windows, Linux et Mac OS X). Dans les prochaines semaines/mois je ferais une application qui permettra de packager une application directement avec les composants que l’on (comme le fait Shoes depuis peu) et quelques petites autres choses pour faciliter le déploiement.
Je vais maintenant pouvoir me concentrer sur l’enrichissement du DSL et de la documentation. Bref encore plein de travail pour ce projet.
When I was going through a minor existential crisis a few years ago, I read the Bible from cover to cover. The copy I had was the rattiest, oldest paperback version…
Ända sedan LaterThis lanserades har jag funderat på ett sätt att visa de mest populära länkarna som sparas. Ungefär som Delicious gör. Men eftersom det bara sparas ett par hundra länkar om dagen så blir det för lite data för att titta på hur ofta en länk blir sparad och använda det som underlag för [...]
or: “what games story can learn from Stephen Moffat”
So Braid finally came out. I was in shock when I saw the release date; wonderful as it was, I was never sure I was going to get a chance to play it. I shouldn’t have worried. It’s out, I’ve got it, and so far, it’s been [...]
Lets first consider simple has_many and belongs_to associations as:
class Article < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :article
end
Now if you wish to index the title of associated article with comment for searching, you just need to add ” is_indexed :fields => :body, :include => [{ :association_name => ‘article’, :field => ‘title’, :as=> [...]
The Rubyist - per rubisti da rubisti - è una rivista per sviluppatori ruby pubblicata da Jeremy McAnally . Costa circa 8$ in versione cartacea e 3$ in pdf su Lulu.
Ci sono interessanti interviste a Rein Henrichs e Hampton Catlin, articoli di Jamie van Dyke, Ben Scofield e Yehuda Katz niente di veramente approfondito [...]
It's impossible not to ponder striking it rich at a start up, but there's another alternative if you're looking to make some good money -- build your brand.
In January of 2005 I created a blog. I truly can't remember why I created it, but I do remember that I was making $60,000 a year. Then in February I joined ThoughtWorks and my blog became part of blogs.thoughtworks.com. I had instant readership, but not a lot to say.
Two and a half years and a lot of blog posts later I turned down an offer that was $174,000 a year. This wasn't $174,000 a year because the work sucks. It was a good job, but I wasn't ready to leave ThoughtWorks. It's been a year since then, and I know it was the right decision.
Now, I didn't make millions, but tripling your salary in two and a half years is still quite nice. There's no question that my brand was responsible for my ever increasing salary requirements. In fact, when I was interviewing two of the three interviewers started their interviews with "I read your material, you've got exactly what we need here. So why don't you ask me the questions instead". My brand had already gotten me the job.
Building a brand isn't as hard as you might think. There's really only 3 things you need to focus on.
Writing
Presenting
Contributing
If you do all three of those, you'll have a brand in no time.
But, before you do those three things, you'll need to read two books that will give you the proper guidance.
note: both books are required reading whether you are building a brand or not.
Once you have the requisite reading covered it's time to make your mark.
Writing Writing isn't hard. Writing well is hard, but you're a programmer, so you needn't worry about that. No one expects you to be a good writer, they're happy if you are, but they're forgiving if you're not. Don't use your poor writing skills as an excuse not to write.
Don't know what to write about? The answers are all around you. Anything you do that's interesting, there's 100 people searching Google for how to do it. Any question a colleague asks you, someone is searching Google for the same answer. Anything that's valuable to you... yes, someone is googling for it.
Take the time to write the answer in a blog entry. People will remember if your blog consistently shows up in their Google searches.
Create a blog. Blogger is free and definitely good enough. Here's a few thoughts on blogging.
Don't roll your own, you don't need the maintenance headache.
Name it something simple, but be sure to include your name. Disco Stu's Ramblings is funny, but you want to build your brand, not Disco Stu's.
Buy your name as a domain and put the blog as a directory (I didn't do this correctly). If I had it to do over my blog would be at http://jayfields.com/blog. This is important for Google Page Rank. If you do it the way I did you'll have different page rank for your homepage and your blog. Not the end of the world, but not ideal.
Keep it focused. If you want to write about programming and gambling, create two different blogs. Also, avoid "Sorry I haven't written in awhile" posts. People aren't dying for your next post. They're subscribed because they want technical content, not stories about how you've been busy remodeling your home.
Keep blog posts short if possible. Anything over 1500 words is article material. If you can't find somewhere to publish the article, then your blog is fine. But, remember that people don't like reading long blog entries (like this one)
At first, stick to writing blog entries. They're not too hard and don't require as much polish. They also let you start building a catalog of material. Once you have enough similar posts, start rolling them into articles to post on InfoQ or other similar sites. Eventually, if you write enough articles, you can roll them up into a book. It will take years, but so does writing a book from scratch and doing it this way allows you to get constant feedback without any deadline pressure.
Presenting Of the 3 things you need to do, I think presenting is the hardest to get going with. You aren't likely to pick up a speaking spot at a good conference if no one has heard of you. So, you'll need to rely on your writing to build your brand a bit, then you can present on the topics that you write about. Alternatively, if you create some open source software that generates buzz you can also pick up a few speaking engagements. Getting started is the hardest part, but once you give a few good talks you'll quickly be turning things down because you just can't fit it in your schedule.
If you're serious about speaking I also highly recommend SpeakEasy. I spent two and a half miserable days at SpeakEasy learning how bad I was at public speaking. The experience was priceless. I can't say enough good things about what I learned in those two and a half days.
Contributing The last suggestion is the easiest. Contribute some open source software. There's so many ways to contribute.
Pick an existing project that you use and create a patch for an outstanding bug.
Extract something interesting from your codebase and release it as open source. You don't need millions of adopters. If you create something valuable to 20 people you'll gain 20 people advocating your brand.
Be the documentation guy. Almost all open source software suffers from poor documentation. Make it your speciality. You'll quickly make friends if you do the work others don't feel like doing.
Join a mailing list for your favorite open source project and be active. Be the guy that's always willing to help the recent adopters.
I'm sure there's other ways as well. It doesn't matter how you contribute, just get out and start contributing.
Oh, and don't submit patches as disco_stus_brother. You're name is your brand, use it.
Why didn’t ANYONE notice how FUCKED UP this is:
These factors led to the development of Automake. automake, like autoconf, is a program run by a developer. The developer writes files named Makefile.am; these use a simpler syntax than ordinary Makefiles. automake reads the Makefile.am files and produces Makefile.in files. The idea is that [...]
Just a quick note: I just read about Adeona, a project from the University of Washington that lets you track a stolen laptop for free (of course you have to install it before you have someone steal it ;-)). The Mac OS version can even take snapshots of the thief with the iSight camera, like this one:
I just installed it and I hope that I'll never need to use it. Having some hooded freak messing with my MacBook Pro is just a too terrible thought to bear.
It's been a long time since I posted last. I figured it was time to get at least a basic update out to folks.
JRuby's been clicking along really well. Perhaps a little too well. Our bug tracker counts 476 open bugs and climbing, even while we're trying to periodically sweep through them. We're slipping behind, but there's a silver lining: every other bug is filed by someone new. So there's happiness in slavery.
My favorite item has to be the improved interpreter performance, which now is clearly faster than MRI's interpreter. So whether you're running interpreted or compiled in JRuby, you should be getting pretty solid straight-line performance.
There were also dozens upon dozens of compatibility fixes, an upgrade to RubyGems 1.2, and lots of other miscellaneous changes to make JRuby a little friendlier and easier to use. It's nice to be able to focus on that kind of stuff now that compatibility is mostly a done deal (ok, high 90th percentile...but pretty darn good).
So then...what's on the slate for the next JRuby release?
Making the Leap?
We had originally been talking about JRuby 1.1.3 being the last planned release in the 1.1 line. It had reached a really solid level of stability and performance, people were putting it in production for all sorts of apps, and we were generally very happy with it. "Last planned release" doesn't mean we wouldn't continue to do maintenance releases as needed...it just means we weren't going to do day-to-day development against the 1.1 line.
The primary reason for this is a number of large-scale projects we'd been putting off. For example, the "Java Integration" (JI) subsystem of JRuby has long been a serious thorn in our sides. Based off probably a dozen different people's contributions over nearly eight years, it had become an impenetrable maze of code, half in Java, half in Ruby, but all clearly in the "suck" column. And I'm not saying anything negative about the contributors who wrote all that suckage (which includes me)...they all made valiant attempts to improve the situation. But a dozen 5% solutions had led us down an ever-more-terrifying rabbit hole. We faced the ultimate decision: fix or rewrite?
We were all set to rewrite. I'd already started an experiment I called "MiniJava", a mostly code-generated replacement for JI that boasted dynamic dispatch speed no slower than Ruby to Ruby and static dispatch speed (from Java into Ruby) only about two times slower than Java calling Java. There were many levels of awesome there, but one serious problem: no tests.
JRuby's JI layer has evolved over a long period of time, and has been worked on by a mix of TDD fans and non-fans. There have also been numerous attempts to rewrite portions of the system, usually ending far short of intentions and with no new tests for functionality added along the way. As a result, any attempt to replace the JI layer would be an exercise in pain: even *we* didn't know how it all works. It's probably not exaggerating to say that existing test cases covered less than half of JI functionality, and that the current JRuby team probably understood less than half of JI's implementation. Not a great place to start from.
Faced with the certainty of pain and knowing, workaholic that I am, that a large portion of the rewrite would probably fall on my shoulders, I decided to give it one more go. I decided to attempt an in-place refactoring of JRuby's Java Integration layer, tens of thousands of lines of spaghetti Java and Ruby code.
Redemption
I've had false starts before. The compiler had at least two partial attempts that failed to go anywhere. I've rewritten the JRuby interpreter several times. Hell, I can't count the number of times I tried to refactor JRuby's IO subsystem before finally succeeding. But JI...man, that is some seriously heinous code. So I had to start small. How about something I was already intimately familiar with: method dispatch.
Here's one of our JI benchmarks. The idea here is that since JRuby's String type is backed by a ByteList, appending to a ByteList through Java integration should be roughly equivalent in execution cost to appending to a String. Or at least, that would be the ideal situations. It was not, however, the case in JRuby 1.1.3.
Ouch. Ten times worse? Sure, I could see it being a couple times worse; after all, going from Ruby code into a Ruby type and back out to Ruby code should be faster than Ruby to Java to Ruby, since we're talking about leaving the controlled world of JRuby core and coming back. But not ten times worse.
Armed with this and a few other benchmarks, I started attacking the dispatch path for Java calls. Largely the optimizations made were the same ones we'd done over the past year for Ruby code: avoid boxing arguments in arrays when possible; clean up and simplify overloaded method selection; as much as possible eliminate constructing any objects not directly used in the eventual reflected call. And early returns started to look really good. Once the basics of the new call logic were in place, performance started to look a lot better.
Here's an example of where improving overload selection made a huge difference. Previously, every time Ruby code called an overloaded Java method, we built up an ArrayList of all argument types, used that to get an aggregate hashcode, used the hashcode to see whether there was a cached previous match, and otherwise went through a brute-force search to match incoming types to outgoing Java signatures.
Wait a second. We constructed an ArrayList just to get a hashcode based on its contents? That dog won't hunt, Monsignor.
So I replaced that logic with a five-line method that aggregates the type's hashcodes into an uber-hashcode, which is then used as the cache key. Combine that with specific-arity searches (avoiding argument boxing in arrays) and search logic that understands Ruby objects (avoiding pre-coercing each argument to potentially the wrong type), and hey, we're starting to see the light.
Keeping it Real
Once it became apparent that a refactoring was most definitely possible, even if it took some hard work and a lot of dedication, we decided to put out a 1.1.4 release, focusing primarily on Java integration, but as always including peripheral bug fixes and performance improvements. Having made that decision, the JI job suddenly became a lot more important. I vowed that 1.1.3 would be the last release to contain a JI layer we were silently afraid of.
Then there was the matter of existing users. Since the beginning of the year, more and more folks have been branching out from the core Rails world that had been JRuby's bread and butter into "Java scripting" sorts of applications. Probably the most prominent ones are the team at Happy Camper Studios, who not only built a real-world-practical Swing framework for JRuby (see MonkeyBars) and a library for packaging up JRuby-based Ruby apps as single-file executables (see Rawr), but who also were pushing the boundaries of what Ruby and JRuby are capable of (see RailGun, and probably see a lot more in the near future). And to top it off, they were releasing MonkeyBars-based apps commercially...making their living depending on JRuby's JI layer.
Would it be a good decision to leave them with the old code for six months while we do a rewrite? I'll let you think about that for a bit.
More Results
Another area that needed serious work was juggling Ruby and Java arrays. The logic for coercing a Ruby array into a Java array was implemented half in Ruby and half in Java, neither half being very efficient in themselves. Add to that the constant back and forth, and you have a recipe for disaster. With another multi-day effort, I managed to wrestle the code to one side of the fence, refactor it, and improve performance over twenty times.
Code
require 'java' require 'benchmark'
TIMES = (ARGV[0] || 5).to_i
TIMES.times do Benchmark.bm(30) do |bm| bm.report("control") {a = [1,2,3,4]; 100_000.times {a}} bm.report("ary.to_java") {a = [1,2,3,4]; 100_000.times {a.to_java}} bm.report("ary.to_java :object") {a = [1,2,3,4]; 100_000.times {a.to_java :object}} bm.report("ary.to_java :string") {a = [1,2,3,4]; 100_000.times {a.to_java :string}} end end
JRuby 1.1.3 user system total real control 0.013000 0.000000 0.013000 ( 0.013130) ary.to_java 7.523000 0.000000 7.523000 ( 7.522787) ary.to_java :object 7.794000 0.000000 7.794000 ( 7.794777) ary.to_java :string 9.905000 0.000000 9.905000 ( 9.905805)
JRuby trunk user system total real control 0.009000 0.000000 0.009000 ( 0.009548) ary.to_java 0.240000 0.000000 0.240000 ( 0.239946) ary.to_java :object 0.248000 0.000000 0.248000 ( 0.247385) ary.to_java :string 0.418000 0.000000 0.418000 ( 0.418230)
You can find similar improvements on trunk for object construction, interface implementation, and several other areas. Work continues, but performance is starting to look way better.
Don't You Think About Anything But Performance?
Of course a side effect of simplifying the code for performance reasons is that fixing bugs and adding features becomes a lot easier. Check out a tiny bit of new logic that works now on JRuby trunk:
# "closure conversion" was only supported for instance methods before thread = java.lang.Thread.new { puts 'Wahoo!' } thread.start thread.join # output: 'Wahoo!'
Of course this is a somewhat contrived example, but there are some obviously useful examples too:
javax.swing.SwingUtilities.invoke_later { puts "Yay, Swing!" } # script terminates, but the Swing event thread keeps running until it's fired our block
The ability to pass a block to "any method" that accepted an interface as its last parameter was only functional for instance methods in all previous releases of JRuby. After the refactoring, expanding it to constructors and static methods took about 5 minutes. With tests. We'll come back to that in a moment.
The simplification of the code also means we'll probably be able to fix a bunch of Java Integration bugs we've punted on for months. For example, it's been a long-standing bug that you can't implement a Java interface in Ruby by defining the underscored versions of that interface's method names. But now, with newly rewritten JI interface-implementation code, it should be a snap to add that feature. We're planning to do a JI bug audit for 1.1.4 and knock down as many long-standing issues as we can.
Proving It Works
So back to the tests for a moment.
Some months ago we managed to get a baseline suite of RSpec specs into the JRuby development process thanks to Nick Sieger. Initially, the tests were very sparse, only a few specific things Nick had a chance to put together. But as interested community members started sending in patches, we started to grow a nice little suite.
As I've been working on the refactoring, I've been trying to "test along" as I learn how bits of JRuby's JI layer function. And so I've added a number of new specs for type coercion, interface implementation, method dispatch and overload selection, and others. Ola Bini came out of hiding to contribute a pretty comprehensive set of Array specs, which were a great help during the slaying of the Array-coercion dragon. So we're finally getting that suite we'd always needed, and once the refactoring is done we'll be in a far better position to start taking JI to the next level.
What's Next?
At the moment the refactoring is maybe 25% along. I'm the only one working on it, and it's a crapload of code, so it's going to take a little time. But most key performance bottlenecks have been remedied at this point.
There are a few areas that remain to be tackled:
Refactoring the extensive logic governing how Ruby classes can extend abstract or concrete Java classes. Kresten Krab Thorup contributed this well over a year ago, and it's kinda been an island unto itself. It will take a considerable effort to rework.
Moving the remaining core JI logic from Ruby into Java. I know, turtles and all that...but I've seen enough projects try to do large-scale refactorings in Ruby to know that the tools and techniques simply aren't there yet. By moving this logic into Java, where it belongs, we'll probably be able to delete 90% of it. That means more room for performance and features, and a much higher likelihood that future enhancements can safely live in Ruby without incurring a severe performance penalty.
Eliminating the old "lower level" and "higher level" Java integration layers. Originally, JRuby's JI was implemented as a set of reflection-like Ruby classes wrapping Java's reflection classes (which comprised the "lower level") and a substantial amount of Ruby code that juggled these reflected bits to represent Java types and make Java calls (the so-called "higher level"). While conceptually this makes some sense, in practice it meant that any call from Ruby to Java actually ended up as dozens, maybe hundreds of Ruby invocations before the target Java method could be invoked. Performance improvements over the past four years were able to improve matters, but largely the only substantial gains have come from, and will continue to come from, eliminating the two separate levels entirely.
I intend for all of this to be in place for JRuby 1.1.4, which we want to release this month.
When working on software design, UI Mockups are quite important and Patrice, colleague of mine at eXo has pointed me to a very cool tool to use when you have to quickly do a mockup, and work with the dev team in an iterative fashion: This tool is "Balsamiq Mockup". Here an example of mockup realized with Balsamiq:
Also if you read more about the tool, you can see that it has native integration
Disclaimer: This is a publicly accessible database. The views and opinions of originators and contributors expressed on this site do not necessarily state or reflect those of DSC Limited. No representation or warranty is given as regards to any applicability of any suggestion, its accuracy or completeness.